Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么正则表达式匹配会得到这个结果?_Python_Regex_Regex Greedy - Fatal编程技术网

Python 为什么正则表达式匹配会得到这个结果?

Python 为什么正则表达式匹配会得到这个结果?,python,regex,regex-greedy,Python,Regex,Regex Greedy,使用元字符+时,模式必须至少出现一次。当我试图在这个字符串中匹配a[ab]+时:abbaabbaaaa使用python的re.findall(),我希望它从第一个字母a开始返回所有这些可能的匹配,就像['ab',abb',abba',abbaaa',等等]一样,直到到达整个字符串(这也是一个匹配)。此外,我认为它也适用于字符串中的每一个a,而不仅仅是第一个,因此我认为匹配的结果将比这更多 这是我使用的代码: import re string = 'abbaaabbbbaaaaa' matche

使用元字符
+
时,模式必须至少出现一次。当我试图在这个字符串中匹配
a[ab]+
时:
abbaabbaaaa
使用python的
re.findall()
,我希望它从第一个字母
a
开始返回所有这些可能的匹配,就像
['ab',abb',abba',abbaaa',等等]
一样,直到到达整个字符串(这也是一个匹配)。此外,我认为它也适用于字符串中的每一个
a
,而不仅仅是第一个,因此我认为匹配的结果将比这更多

这是我使用的代码:

import re

string = 'abbaaabbbbaaaaa'
matches = re.findall('a[ab]+', string)
for match in matches:
    print(match)

但是,结果只是
abbaabbaaaaa
(整个字符串)。那么我理解错了什么呢?

方括号是一个字符类,意思是匹配这些字符中的任何一个

因此,
[ab]+
匹配一行中的一个或多个a或b字符。你的模式将吞噬整个字符串与一个单一的匹配

您可能想要的是:

re.findall('a(?:ab)+', string)

请注意,
(?:
是非捕获组。它的工作原理与此模式中的
相同,但效率更高,因为它不保存子组(您不需要这些子组)。

a[ab]+
将匹配单个字符串(假设它完全匹配)。整个字符串
abbaabbaaaa
与该正则表达式匹配,因此您得到一个匹配项:整个字符串。它不会给你每一个可能匹配的小片段


换言之,
a
[ab]
的每个匹配“消耗”一个字符。也就是说,匹配的字符被“用完”,程序移动到下一个字符。一般来说,这就是您想要的:您想要查看整个字符串是否匹配,或者其中有多少匹配,而不是查找组成更大匹配的所有比特和片段。

正则表达式只查找不重叠的匹配(除非您使用像with这样的特殊技巧)

此外,默认情况下,
+
是贪婪的,匹配尽可能多的字符。如果向它添加一个
,它将变为惰性,因此它将在第一个可能的点停止。这将为您提供一个非重叠匹配的列表,但这也不是您所期望的:

['ab', 'aa', 'ab', 'aa', 'aa']
# as in ABbAAABbbbAAAAa
如果你这样做

matches = re.findall('(?=(a[ab]+))', string)
您可以从字符串中的每个可能起点获取所有匹配项:

['abbaaabbbbaaaaa',
 'aaabbbbaaaaa',
 'aabbbbaaaaa',
 'abbbbaaaaa',
 'aaaaa',
 'aaaa',
 'aaa',
 'aa']
通过将正则表达式递归地应用于所有这些子匹配,您将获得所有可能的匹配(非常多)