Regex: сопоставлять скобки как жадные, так и не жадные - PullRequest
5 голосов
/ 20 мая 2011

Я использую модуль регулярных выражений python, re.

Мне нужно сопоставить что-либо внутри '(' ')' в этих двух фразах, но "не так уж жадно".Например:

show the (name) of the (person)

calc the sqrt of (+ (* (2 4) 3))

Результат должен возвращаться из фразы 1:

name
person

Результат должен возвращаться из фразы 2:

+ (* (2 4) 3)

Проблема заключается вчто, чтобы соответствовать первой фразе, я использовал '\(.*?\)'

Это, во второй фразе, просто подходит + (* (2 4)

И использование '\(.*\)', чтобы соответствовать второй фразе правильно, на первой фразе подходит(name) of the (person)

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

Ответы [ 4 ]

6 голосов
/ 20 мая 2011

Pyparsing облегчает написание простых одноразовых синтаксических анализаторов для таких вещей:

>>> text = """show the (name) of the (person)
...
... calc the sqrt of (+ (* (2 4) 3))"""
>>> import pyparsing
>>> for match in pyparsing.nestedExpr('(',')').searchString(text):
...   print match[0]
...
['name']
['person']
['+', ['*', ['2', '4'], '3']]

Обратите внимание, что вложенные паренсы были отброшены, а вложенный текст возвращен каквложенная структура.

Если вы хотите исходный текст для каждого бита в скобках, используйте модификатор originalTextFor:

>>> for match in pyparsing.originalTextFor(pyparsing.nestedExpr('(',')')).searchString(text):
...   print match[0]
...
(name)
(person)
(+ (* (2 4) 3))
0 голосов
/ 20 мая 2011

Соответствует всей необходимой информации:

(?:\()(.*?\){2})|(?:\()(.*?)(?:\))

Группа 1 = + (* (2 4) 3)

  • Последняя ") "можно удалить с помощью .strip (')')

Группа 2 = имя , персона

0 голосов
/ 20 мая 2011

То, что вы пытаетесь сделать, похоже на маневровый двор (на самом деле это похоже на LISP, поэтому, возможно, вам стоит проверить PyLisp ).Нет необходимости использовать регулярные выражения для анализа таких выражений.

См. Маневровый двор article @ wikipedia и его Python реализация .

0 голосов
/ 20 мая 2011

Пока скобки не являются вложенными, вы можете использовать ленивое регулярное выражение:

\(.*?\)

Хотя теоретически вы можете анализировать ограниченное количество вложений в регулярном выражении, это очень сложно и не стоит усилий. Это гораздо проще сделать с помощью пользовательской функции Python. См. этот ответ для хорошего объяснения.

...