Регулярное выражение в Python - PullRequest
1 голос
/ 15 июня 2009

Цель: учитывая число (оно может быть очень длинным и больше 0), я бы хотел, чтобы пять наименее значащих цифр отбрасывали любой 0 в конце этого числа.

Я пытался решить эту проблему с помощью регулярных выражений. При помощи RegexBuddy я пришел к этому:

[\d]+([\d]{0,4}+[1-9])0*

Но python не может скомпилировать это.

>>> import re
>>> re.compile(r"[\d]+([\d]{0,4}+[1-9])0*")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/re.py", line 188, in compile
    return _compile(pattern, flags)
  File "/usr/lib/python2.5/re.py", line 241, in _compile
    raise error, v # invalid expression
sre_constants.error: multiple repeat

Проблема в том, что "+" после "{0,4}", похоже, не работает в python (даже в 2.6)

Как мне написать рабочее регулярное выражение?

PS: Я знаю, что вы можете начать деление на 10, а затем использовать остаток n% 100000 ... но это проблема с регулярным выражением.

Ответы [ 5 ]

10 голосов
/ 15 июня 2009

Это регулярное выражение очень излишне. Попробуйте это:

>>> import re
>>> re.compile(r"(\d{0,4}[1-9])0*$")

Приведенное выше регулярное выражение предполагает, что число является действительным (например, оно также будет соответствовать «abc 012345 0».) Если вам действительно нужна проверка на отсутствие нецифровых символов, вы может использовать это:

>>> import re
>>> re.compile(r"^\d*?(\d{0,4}[1-9])0*$")

В любом случае, \d не обязательно должен находиться в классе символов, и квантификатор {0,4} не нужно заставлять быть жадным (как указывает дополнительный +, хотя, очевидно, Python не распознает, что .)

Кроме того, во втором регулярном выражении \d не является жадным, так как я считаю, что это улучшит производительность и точность. Я также сделал это "ноль или больше", поскольку я предполагаю, что это то, что вы хотите.

Я также добавил якоря, так как это гарантирует, что ваше регулярное выражение не будет совпадать с чем-либо в середине строки. Если это то, что вы хотели (хотя вы сканируете длинный текст?), Удалите якоря.

5 голосов
/ 16 июня 2009

\ d {0,4} + - это собственный квантификатор, поддерживаемый некоторыми разновидностями регулярных выражений, такими как .NET и Java. Python не поддерживает собственнические квантификаторы.

В RegexBuddy выберите Python на панели инструментов вверху, и RegexBuddy скажет вам, что Python не поддерживает собственнические квантификаторы. Знак + будет выделен красным цветом в регулярном выражении, а вкладка «Создать» укажет на ошибку.

Если вы выберете Python на вкладке «Использование» в RegexBuddy, RegexBuddy сгенерирует фрагмент исходного кода Python с регулярным выражением без собственнического квантификатора и комментарий, указывающий, что удаление собственнического квантификатора может привести к другим результатам. Вот код Python, который RegexBuddy генерирует с помощью регулярного выражения из вопроса:

# Your regular expression could not be converted to the flavor required by this language:
# Python does not support possessive quantifiers

# Because of this, the code snippet below will not work as you intended, if at all.

reobj = re.compile(r"[\d]+([\d]{0,4}[1-9])0*")

Что вы, вероятно, сделали, - это выберите вариант, такой как Java, на главной панели инструментов, а затем нажмите «Копировать регулярное выражение в качестве строки Python». Это даст вам регулярное выражение Java в формате строки Pythong. Элементы в меню «Копировать» не преобразуют ваше регулярное выражение. Они просто форматируют это как строку. Это позволяет вам делать такие вещи, как форматирование регулярного выражения JavaScript в виде строки Python, чтобы ваш серверный сценарий Python мог передавать регулярное выражение в клиентский код JavaScript.

2 голосов
/ 15 июня 2009

Небольшой совет. Я рекомендую вам протестировать reTest вместо RegExBuddy. Существуют разные механизмы регулярных выражений для разных языков программирования. ReTest ценен тем, что позволяет быстро тестировать строки регулярных выражений внутри самого Python. Таким образом, вы можете быть уверены, что протестировали свой синтаксис с помощью механизма регулярных выражений Python.

0 голосов
/ 13 сентября 2012

Это мое решение.

re.search(r'[1-9]\d{0,3}[1-9](?=0*(?:\b|\s|[A-Za-z]))', '02324560001230045980a').group(1)

4598 '

  • [1-9] - номер должен начинаться с 1 - 9
  • \d{0,3} - 0 или 3 цифры
  • [1-9] - номер должен заканчиваться цифрой 1 или 9
  • (?=0*(:?\b|\s\|[A-Za-z])) - конечная часть строки должна быть сформирована из 0 и или \b, \s, [A-Za-z]
0 голосов
/ 15 июня 2009

Ошибка, по-видимому, в том, что у вас есть два квантификатора подряд, {0,4} и +. Если + не предназначен для буквального обозначения здесь (в чем я сомневаюсь, поскольку вы говорите о числах), то я не думаю, что вам это нужно вообще. Разве это означает что-то другое в этой ситуации (возможно, жадность квантификатора {})? Я бы попробовал

[\d]+([\d]{0,4}[1-9])0*

Если вы действительно намеревались применить оба квантификатора, то это может сработать

[\d]+(([\d]{0,4})+[1-9])0*

Но, учитывая ваше описание проблемы, я сомневаюсь, что вы этого хотите.

...