如何在Python中实现递归正则表达式?

15

我很感兴趣如何在Python中实现递归正则表达式匹配(我没有找到任何例子 :()。例如,如何编写一个表达式来匹配像"foo(bar(bar(foo)))(foo1)bar1"这样的“括号平衡”的字符串。


1
@Tempus,确实,或者Tony会来。https://dev59.com/X3I-5IYBdhLWcg3wq6do#1732454 - Prof. Falken
1
@AmigableClarkKant 没关系,我认识Tony。他是我的朋友。 - Geo
5个回答

15
你可以使用 pyparsing
#!/usr/bin/env python
from pyparsing import nestedExpr
import sys
astring=sys.argv[1]
if not astring.startswith('('):
    astring='('+astring+')'

expr = nestedExpr('(', ')')
result=expr.parseString(astring).asList()[0]
print(result)

运行它将产生以下结果:

% test.py "foo(bar(bar(foo)))(foo1)bar1"
['foo', ['bar', ['bar', ['foo']]], ['foo1'], 'bar1']

11

这是一个老问题,但是对于通过搜索来到这里的人:

有一种Python的替代正则表达式模块支持递归模式: https://pypi.python.org/pypi/regex

它在re上还有很多更好的改进。


1
太棒了,新引擎!终于有了不错的递归 :) 谢谢。 - chtenb
2
这个引擎会在某个时候合并到Python的标准库中吗?我似乎找不到任何最近的讨论。 - chtenb
2
这个回答如果附带一个例子会更有益! :) - Andy Hayden

4

您无法使用正则表达式完成此操作。Python不支持递归正则表达式。


3

2
使用PyPi正则表达式,你可以轻松安装它,只需使用pip install regex命令即可。接下来,你可以使用它进行相关操作。
import regex

pattern = r'[^()]*+(\((?>[^()]|(?1))*+\)[^()]*+)++'
text = 'foo(bar(bar(foo)))(foo1)bar1'
print(bool(regex.fullmatch(pattern, text)))
# => True

请查看Python演示,查看正则表达式模式演示(请注意,在演示中添加了\A\z锚点,因为regex.fullmatch需要完全匹配字符串)。 模式细节
  • \A - 在regex.fullmatch中隐含 - 字符串的开头
  • [^()]*+ - 0个或多个字符,不包括()(占有匹配,不允许回溯到模式中)
  • (\((?>[^()]|(?1))*+\)[^()]*+)++ - 1个或多个出现的第1组模式:
    • \( - (字符
    • (?>[^()]|(?1))*+ - 1个或多个重复(占有匹配)的
      • [^()] - 除()之外的任何字符
      • | - 或
      • (?1) - 递归第1组模式的正则表达式子程序
    • \) - )字符
    • [^()]*+ - 0个或多个字符,不包括()(占有匹配)
  • \z - 在regex.fullmatch中隐含 - 字符串的结尾。
请在regular-expressions.info上查看模式和更多有关正则表达式子程序的信息

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接