我理解模式r'([a-z]+)\1+'
正在搜索字符串中搜索重复的多字符模式,但我不明白为什么k2
回答不是' aaaaa&# 39; (5' a'):
import re
k1 = re.search(r'([a-z]+)\1+', 'aaaa')
k2 = re.search(r'([a-z]+)\1+', 'aaaaa')
k3 = re.search(r'([a-z]+)\1+', 'aaaaaa')
print(k1) # <_sre.SRE_Match object; span=(0, 4), match='aaaa'>
print(k2) # <_sre.SRE_Match object; span=(0, 4), match='aaaa'>
print(k3) # <_sre.SRE_Match object; span=(0, 6), match='aaaaaa'>
Python 3.6.1
答案 0 :(得分:6)
因为+贪婪。
([a-z]+)
首先匹配'aaaaa',然后它回溯直到\1+
匹配字符串,然后停止。因为'aa'是允许([a-z]+)
成功匹配的\1
的第一个值,所以它就会返回。
答案 1 :(得分:2)
这里的关键概念是回溯。每当模式包含具有不同长度的量化子模式时,正则表达式引擎可以以各种方式匹配字符串,并且一旦量化部分之后的正则表达式的一部分无法匹配某些子字符串,它就可以回溯,即免费一个属于量化模式的char,并尝试与后续的子模式匹配。
看一下大局:
让我们看看在跳过更长的例子之前,字符串的匹配程度是多少......
现在,为什么a
不匹配?因为[a-z]+
和\1+
需要匹配至少1个字符,所以必须至少有2个字符。
aa
匹配,因为第一个([a-z]+)
首先匹配整个字符串,然后回溯以适应\1+
模式的某些文本(并且它匹配第二个a
) ,所以有一场比赛。
三个a
字符串aaa
作为一个整体匹配,因为第一个([a-z]+)
首先匹配整个字符串,然后回溯以适应\1+
模式的一些文本(注意捕获组只需要保留一个a
,因为尝试使用两个aa
时,\1+
无法匹配最后的第三个a
),并且匹配三个a
秒。
现在,来看问题中的示例
aaaa
字符串完整匹配与aa
匹配的方式类似:捕获组模式首先抓取整个aaaa
,然后从\1+
开始回溯必须“找到”一些文本,并且正则表达式引擎会尝试将aaa
捕获到组1中。但是,\1+
无法匹配3 a
s,因此回溯继续,当有第1组中有两个a
,量化的反向引用与最后两个a
匹配。
现在k2
案例:
aaaaa
字符串匹配如下:
aaaaa
并将其放入具有([a-z]+)
部分\1+
找不到任何文字,引擎重试与字符串不一致,因为\1+
之前的部分可以匹配不同的文字,这要归功于+
量词aaaa
(=置于第1组),但由于\1+
不匹配(因为\1
尝试匹配aaaa
,但无效)在字符串结尾之前只留下a
aaa
再次尝试无效(因为\1
尝试匹配aaa
,但只剩下两个a
了)aa
被放入第1组,\1
与第3和第4 a
匹配,这是唯一匹配,因为字符串中只剩下一个a
。 这是sample scheme of how the string is matched:
无法匹配最后一个a
: