Регулярное выражение для поля фиксированной ширины
Мне нужно сопоставить поле фиксированной ширины в макете файла с регулярным выражением. Поле числовое / целое, всегда имеет четыре символа и входит в диапазон 0..1331. Когда число меньше 1000, строка заполняется левыми нулями. Так что все эти примеры верны:
- 0000
- 0001
- 0010
- 1000
- 1331
Но следующее не должно быть принято:
- 1
- 01
- 10
- 100
- 4759
Было бы хорошо, если бы я мог применять это ограничение только с помощью регулярных выражений. Немного поиграв, я дал выражение \0*[0-1331]\
, Проблема в том, что он не ограничивает размер до четырех символов. Конечно я мог сделать \000[0-9]|00[10-99]|0[100-999]|[1000-1331]\
но я отказываюсь использовать что-то противное. Кто-нибудь может придумать лучший способ?
2 ответа
Регулярные выражения не являются ответом на каждую проблему. Мой совет будет делать что-то вроде:
boolean isValidSomethingOrOther (string):
if string.length() != 4:
return false
for each character in string:
if not character.isNumeric():
return false
if string.toInt() > 1331:
return false
return true
Если вы должны использовать регулярное выражение, в вашем решении нет ничего плохого, но я бы, вероятно, использовал следующий вариант (только исходя из моего понимания механизмов RE и их работы):
^0[0-9]{3}|1[0-2][0-9]{2}|13[0-2][0-9]|133[01]$
- Первый раздел соответствует 0000-0999.
- Второй матч 1000-1299.
- Третий матч 1300-1329.
- Финал соответствует 1330 и 1331.
Обновить:
Просто на комментарий элегантности, есть много форм элегантности, из которых являются регулярные выражения. Вы также можете достичь элегантности, просто абстрагируя валидацию от отдельной функции или макроса, а затем вызывая ее из своего кода:
if isValidSomethingOrOther(str) ...
где SomethingOrOther
это конкретный бизнес-объект. Это позволяет вам легко изменить представление о допустимом объекте, даже используя регулярное выражение по вашему желанию или любые другие проверки, которые вы считаете подходящими (например, мою функцию выше).
Это позволяет вам учитывать любые изменения в будущем, такие как требование, чтобы эти объекты теперь были простыми числами.
Я уверен, что мог бы написать регулярное выражение "простое число меньше 1332". Я в равной степени уверен, что не хотел бы - я бы предпочел закодировать это как функцию (или таблицу поиска для необработанной скорости), тем более что регулярное выражение, скорее всего, будет выглядеть так:
^2|3|5|7| ... |1327$
тем не мение.
Это кажется слишком простым, правильно ли я понимаю проблему?
\[01][0-9]{3}\
Я не знаю, что.. означает, целое число в диапазоне? Это должно быть перлизм или что-то в этом роде.
Кажется, это работает так, как вы хотите мне:
In [3]: r = re.compile(r'[01][0-9]{3}')
In [4]: r.match('0001')
Out[4]: <_sre.SRE_Match object at 0x2fa2d30>
In [5]: r.match('1001')
Out[5]: <_sre.SRE_Match object at 0x2fa2cc8>
In [6]: r.match('2001')
In [7]: r.match('001')
In [8]: