Нежадные регулярные выражения Python - PullRequest
117 голосов
/ 20 апреля 2009

Как мне сделать регулярное выражение Python, подобное "(. *)", Так что, если "a (b) c (d) e" python соответствует "b" вместо "b) c (d"?

Я знаю, что могу использовать "[^)]" вместо ".", Но я ищу более общее решение, которое делает мое регулярное выражение немного чище. Есть ли способ сказать python "эй, сопоставьте это как можно скорее"?

Ответы [ 6 ]

144 голосов
/ 20 апреля 2009

Ты ищешь всесильного '*?'

http://docs.python.org/3/howto/regex.html#greedy-versus-non-greedy

не жадные квалификаторы * ?, + ?, ?? или {m, n}? [...] соответствует как мало текст насколько возможно.

59 голосов
/ 20 апреля 2009
>>> x = "a (b) c (d) e"
>>> re.search(r"\(.*\)", x).group()
'(b) c (d)'
>>> re.search(r"\(.*?\)", x).group()
'(b)'

Согласно документам :

Определители '*', '+' и '?' все жадные; они соответствуют как можно большему количеству текста. Иногда такое поведение нежелательно; если RE <.*> сопоставлено с '<H1>title</H1>', оно будет соответствовать всей строке, а не только '<H1>'. Добавление '?' после того, как квалификатор заставляет его выполнять матч нежадным или минимальным образом; будет найдено как можно меньше символов. Использование .*? в предыдущем выражении будет соответствовать только '<H1>'.

13 голосов
/ 20 апреля 2009

Не будет \\(.*?\\) работать? Это не жадный синтаксис.

5 голосов
/ 21 апреля 2009

Как другие сказали, используя? Модификатор * quantifier решит вашу непосредственную проблему, но будьте осторожны, вы начинаете отклоняться в области, где перестанут работать регулярные выражения, и вместо этого вам нужен анализатор. Например, строка "(foo (bar)) baz" вызовет у вас проблемы.

4 голосов
/ 21 апреля 2009

Использование неадекватного матча - хорошее начало, но я бы также посоветовал вам пересмотреть любое использование .* - как насчет этого?

groups = re.search(r"\([^)]*\)", x)
3 голосов
/ 20 апреля 2009

Хотите, чтобы оно совпадало с "(b)"? Делай, как предложили Цитракс и Паоло. Вы хотите, чтобы это соответствовало "b"? У

>>> x = "a (b) c (d) e"
>>> re.search(r"\((.*?)\)", x).group(1)
'b'
...