当前位置: 首页 > 知识库问答 >
问题:

如何在python中找到所有可能的正则表达式匹配?

庄阿苏
2023-03-14

我试图用python及其正则表达式找到所有可能的单词/标记对或其他嵌套组合。

sent = '(NP (NNP Hoi) (NN Hallo) (NN Hey) (NNP (NN Ciao) (NN Adios)))'

def checkBinary(sentence):
    n = re.findall("\([A-Za-z-0-9\s\)\(]*\)", sentence)
    print(n)

checkBinary(sent)

Output:
['(NP (NNP Hoi) (NN Hallo) (NN Hey) (NNP (NN Ciao) (NN Adios)))']

寻找:

['(NP (NNP Hoi) (NN Hallo) (NN Hey) (NNP (NN Ciao) (NN Adios)))', 
 '(NNP Hoi)', 
 '(NN Hallo)',
 '(NN Hey)', 
 '(NNP (NN Ciao) (NN Adios))',
 '(NN Ciao)',
 '(NN Adios)']

我认为正则表达式也可以找到嵌套的括号单词/标记对,但它不返回它们。我该怎么做?

共有2个答案

姜飞飙
2023-03-14

zmo说得对,在语言理论中,正则语言是由有限状态自动机表示的,但是正则表达式使用任何回溯形式,比如那些使用捕获组、查找组等的正则表达式在现代语言中,不能用语言理论中已知的FSA来表示。如何用DFA或偶数和NFA表示像(\w)\1这样的模式?

(?=(\((?:[^\)\(]*\([^\)]*\)|[^\)\(])*?\)))

我测试了这个http://regexhero.net/tester/

匹配在捕获的组中:

1:(NP(NNP-Hoi)(NN-Hallo)(NN-Hey)(NNP(NN-Ciao)(NN-Adios))

1:(北角海)

1:(NN哈罗)

1:(嘿嘿)

1:(NNP(NN Ciao)(NN Adios))

1:(NN Ciao)

1:(NN Adios)

宗鸿博
2023-03-14

实际上,使用正则表达式是不可能做到这一点的,因为正则表达式表达的是一种由正则语法定义的语言,可以由非有限确定性自动机来解决,其中匹配由状态表示;然后,为了匹配嵌套括号,您需要能够匹配无限多个括号,然后拥有一个具有无限多个状态的自动机。

为了解决这个问题,我们使用了所谓的下推自动机,用于定义上下文无关语法。

因此,如果您的正则表达式与嵌套括号不匹配,那是因为它表示以下自动机,并且与您的输入不匹配:

玩它

请参考麻省理工学院关于该主题的课程:

  • http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-045j-automata-computability-and-complexity-spring-2011/lecture-notes/MIT6_045JS11_lec04.pdf

因此,有效解析字符串的方法之一是为嵌套括号构建语法(pip install pyparsingfirst):

>>> import pyparsing
>>> strings = pyparsing.Word(pyparsing.alphanums)
>>> parens  = pyparsing.nestedExpr( '(', ')', content=strings)
>>> parens.parseString('(NP (NNP Hoi) (NN Hallo) (NN Hey) (NNP (NN Ciao) (NN Adios)))').asList()
[['NP', ['NNP', 'Hoi'], ['NN', 'Hallo'], ['NN', 'Hey'], ['NNP', ['NN', 'Ciao'], ['NN', 'Adios']]]]

注意:有一些正则表达式引擎确实使用下推实现嵌套括号匹配。默认的pythonre引擎不是其中之一,但是存在一个替代引擎,称为regexpip安装regex),它可以进行递归匹配(这使得re引擎上下文自由),参见此代码片段:

>>> import regex
>>> res = regex.search(r'(?<rec>\((?:[^()]++|(?&rec))*\))', '(NP (NNP Hoi) (NN Hallo) (NN Hey) (NNP (NN Ciao) (NN Adios)))')
>>> res.captures('rec')
['(NNP Hoi)', '(NN Hallo)', '(NN Hey)', '(NN Ciao)', '(NN Adios)', '(NNP (NN Ciao) (NN Adios))', '(NP (NNP Hoi) (NN Hallo) (NN Hey) (NNP (NN Ciao) (NN Adios)))']
 类似资料:
  • 问题内容: 我正在尝试使用python及其正则表达式查找所有可能的单词/标记对或其他嵌套组合。 寻找: 我认为正则表达式公式也可以找到嵌套的括号单词/标记对,但它不会返回它们。我应该怎么做? 问题答案: 实际上,不可能使用正则表达式来做到这一点,因为正则表达式表达了一种由 正则 语法定义的语言,该语言可以通过非限定性自动机来解决,其中匹配由状态表示;然后要匹配嵌套的括号,您需要能够匹配无限数量的括

  • 问题内容: 从那时起,我一直在TutorialsPoint上查看代码,此后一直困扰着我……看一下这段代码: 此代码成功打印: 但是根据正则表达式,为什么它不返回其他可能的结果,例如: 要么 如果此代码不适合这样做,那么我该如何编写一个可以找到所有可能匹配项的代码? 问题答案: 这是因为的贪婪,随之而来的是回溯。 字串: 正则表达式: 我们都知道那是贪婪的,并且尽可能匹配所有字符。因此,第一个匹配所

  • 问题内容: 我正在尝试在Python 2.6中使用re查找更大系列的数字中的每10位数字系列。 我很容易就能抓住不重叠的比赛,但我希望数字系列中的每场比赛。例如。 在中 我应该得到以下列表: 我已经找到了“超前”的引用,但是我所看到的示例仅显示数字对,而不是较大的分组,而且我无法将其转换为两位数以外的数字。 问题答案: 在前瞻范围内使用捕获组。前瞻捕捉你感兴趣的文本,但是实际匹配在技术上是前瞻之前

  • 我试图使用Python2.6中的re在一个更大的数字系列中找到每10位数字系列。 我很容易抓住没有重叠的比赛,但我想要的每一个比赛在数字系列。例如。 在“123456789123456789” 我应该得到以下列表: 我发现了对“前瞻”的引用,但我看到的示例只显示了数字对,而不是更大的分组,并且我无法将它们转换成两位数以外的数字。

  • 当所有组都是可选的时,我在提取组时遇到了问题。 上下文(如果您愿意,可以跳到结尾):这是在将字符串与一堆正则表达式进行最佳匹配并查看哪个表达式具有最多组匹配的上下文中。 例如,我可能有一个潜在的格式; 但我希望用户打错字,或者不包含空格或其他东西。 所以我可以用绳子测试一下 并希望获得组 一个 光盘 1-1 G 而且,对于测试字符串 我想得到   DE   克 下面是我的正则表达式,用于匹配以下可

  • 问题内容: 我正在解析的字符串中可能包含任意数量的带引号的字符串(我在解析代码,并尝试避免使用PLY)。我想找出是否有子字符串被引用,并且我有子字符串索引。我最初的想法是使用re查找所有匹配项,然后找出它们代表的索引范围。 似乎我应该将re与类似的正则表达式一起使用(目前,我避免使用三引号和此类字符串)。当我使用findall()时,会得到一个匹配字符串的列表,虽然有些不错,但我需要索引。 我的子