使用元字符+
时,模式必须至少出现一次。尝试使用python的a[ab]+
匹配此字符串abbaaabbbbaaaaa
中的re.findall()
时,我希望它从a
开始,从第一个字母['ab', 'abb', 'abba', 'abbaaa', ... etc]
开始返回所有可能的匹配项直到达到整个字符串(这也是一个匹配)。此外,我认为它也适用于字符串中的每个a
,而不仅仅是第一个,所以我认为匹配的结果将超过这个。
这是我使用的代码:
import re
string = 'abbaaabbbbaaaaa'
matches = re.findall('a[ab]+', string)
for match in matches:
print(match)
但是,结果只有abbaaabbbbaaaaa
(整个字符串)。那么我理解错了什么呢?
答案 0 :(得分:3)
a[ab]+
将匹配单个字符串(假设它完全匹配)。整个字符串abbaaabbbbaaaaa
与该正则表达式匹配,因此您获得一个匹配:整个字符串。它没有给你所有可能匹配的小块。
换句话说,a
和[ab]
的每个匹配都会消耗一个字符。也就是说,匹配字符“用完”,程序移动到下一个字符。一般来说,这就是你想要的:你想看看整个字符串是否匹配,或者它是多少匹配,而不是找到构成更大匹配的所有比特。
答案 1 :(得分:3)
正则表达式只能找到不重叠的匹配(除非您使用positive lookahead assertions和capturing groups等特殊技巧。)
此外,您的+
quantifier默认情况下是贪婪的,匹配尽可能多的字符。如果你向它添加?
,它会变得懒惰,所以它会在第一个可能的点停止。这会给你一个非重叠匹配的列表,但这并不是你所期望的:
['ab', 'aa', 'ab', 'aa', 'aa']
# as in ABbAAABbbbAAAAa
如果你这样做
matches = re.findall('(?=(a[ab]+))', string)
您可以从字符串中的每个可能起点获得所有匹配项:
['abbaaabbbbaaaaa',
'aaabbbbaaaaa',
'aabbbbaaaaa',
'abbbbaaaaa',
'aaaaa',
'aaaa',
'aaa',
'aa']
通过递归地将正则表达式应用于所有这些子匹配,您将获得所有可能的匹配(这些匹配非常多)。
答案 2 :(得分:0)
括号是一个字符类,意味着匹配这些字符中的任何一个。
因此,[ab]+
匹配一行或多行的一个或多个字符。您的模式将通过一次匹配吞噬整个字符串。
您可能想要的是:
re.findall('a(?:ab)+', string)
请注意,(?:
... )
是非捕获组。它在此模式中与(
... )
的工作方式相同,但效率更高,因为它不会保存子组(您不需要)。