Регулярное выражение для поля фиксированной ширины

Мне нужно сопоставить поле фиксированной ширины в макете файла с регулярным выражением. Поле числовое / целое, всегда имеет четыре символа и входит в диапазон 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]: 
Другие вопросы по тегам