我知道模式r'([a-z]+)\1+'是在搜索字符串中搜索重复的多字符模式,但我不明白为什么如果k2答案不是'aaaaa'(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'>
Run Code Online (Sandbox Code Playgroud)
Python 3.6.1
这里的关键概念是回溯。每当一个模式包含不同长度的量化子模式时,正则表达式引擎可能会以各种方式匹配字符串,并且一旦量化部分之后的正则表达式的一部分无法匹配某些子字符串,它可以回溯,即释放属于量化部分的字符模式并尝试与后续子模式匹配。
看一下更大的图景:
在跳到较长的示例之前,让我们看看较短的字符串如何匹配......
现在,为什么a不匹配?因为必须至少有 2 个字符,[a-z]+并且\1+需要匹配至少 1 个字符。
aa是匹配的,因为第一个([a-z]+)首先匹配整个字符串,然后回溯以适应\1+模式的一些文本(并且它匹配第二个a),因此存在匹配。
三a字符串aaa匹配作为一个整体,因为第一个([a-z]+)字符串首先匹配整个字符串,然后回溯以适应模式的一些文本\1+(注意捕获组必须只保留一个,a因为当尝试使用两个时aa,\1+失败了最后的第三个a),并且有一个 3 的匹配a。
现在,来看问题中的例子
字符串aaaa的整体匹配与匹配的方式类似aa:捕获组模式aaaa首先捕获整个字符串,然后回溯,因为\1+还必须“找到”一些文本,并且正则表达式引擎尝试捕获aaa到组 1。但是,\1+无法匹配3 as,所以回溯继续进行,当第 1 组中有两个as 时,量化后向引用与最后两个as 匹配。
还有k2现在的情况:
字符串aaaaa匹配如下:
aaaaa([a-z]+)被抓取并与零件一起放入第 1 组\1+找不到任何文本,引擎会重新尝试以不同的方式匹配字符串,因为\1+由于+量词,可以匹配不同的文本之前的部分aaaa尝试过(=放入组1),但由于\1+不匹配而无济于事(因为然后\1尝试匹配,但在字符串末尾之前只剩下aaaa)aaaa再次尝试,无济于事(\1尝试匹配aaa,但只剩下两个as )aa被放入第 1 组,\1匹配第三个和第四个as,并且这是唯一的匹配项,因为a字符串中只剩下一个。以下是字符串匹配方式的示例方案:
最后一个a无法匹配: