Регулярное выражение для поля фиксированной ширины - PullRequest
4 голосов
/ 21 августа 2009

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

7 голосов
/ 21 августа 2009

Регулярные выражения не являются ответом на каждую отдельную проблему. Мой совет будет делать что-то вроде:

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$

в любом случае.

1 голос
/ 21 августа 2009

Это кажется слишком простым, я правильно понимаю проблему?

\[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]: 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...