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']
通过将正则表达式递归地应用于所有这些子匹配,您将获得所有可能的匹配(非常多)