3 回答
TA贡献1898条经验 获得超8个赞
使用这种基于前瞻性的正则表达式,您可能无法完全按照所讨论的那样获得,但会非常接近。
r'(?=(.+)\1\1)'
代码:
>>> reg = re.compile(r'(?=(.+)\1\1)')
>>> reg.findall('aaabbbxxx_aaabbbxxx_aaabbbxxx_')
['aaabbbxxx_', 'b', 'x', 'a', 'b', 'x', 'a', 'b', 'x']
>>> reg.findall('lalala luuluuluul')
['la', 'luu', 'uul']
正则表达式详细信息:
由于我们将前瞻用作完整的正则表达式,因此我们并没有真正消耗字符,因为前瞻是零宽度匹配。这允许我们从输入中返回重叠的匹配项。
使用findall
我们只返回正则表达式中的捕获组。
(?=
: 开始前瞻(.+)
:匹配 1 个或多个任意字符(贪心)并在组 #1 中捕获\1\1
: 使用反向引用匹配第 1 组的第 2 次出现\1\1
)
: 结束前瞻
TA贡献1812条经验 获得超5个赞
re.findall()不会找到重叠的匹配项。但是您可以使用捕获组找到非重叠匹配,然后使用与该组的反向引用相匹配的正前瞻。
>>> import re
>>> regex = r'(.+)(?=\1{2})'
>>> re.findall(regex, 'aaabbbxxx_aaabbbxxx_aaabbbxxx_')
['aaabbbxxx_', 'a', 'b', 'x', 'a', 'b', 'x']
>>> re.findall(regex, 'lalala luuluuluul')
['la', 'luu']
>>>
这将找到最长的匹配;如果您更改(.+)为,(.+?)您将在每个点获得最短的匹配项。
>>> regex = r'(.+?)(?=\1{2})'
>>> re.findall(regex, 'aaabbbxxx_aaabbbxxx_aaabbbxxx_')
['a', 'b', 'x', 'a', 'b', 'x', 'a', 'b', 'x']
TA贡献1828条经验 获得超3个赞
不先定义子模式是不可能的。
无论如何,如果子模式只是 <any_alphanumeric>,那么re.findall(<the_regex>, 'aaabbbxxx_aaabbbxxx_aaabbbxxx_')
会产生如下内容:
['a', 'b', 'x', 'aa', 'ab', 'bb', 'bx', 'xx', 'x_', 'aaa', 'aaab', 'aaabb', ....]
即,每个字母数字组合重复三次 - 所以有很多组合,而不仅仅是['a', 'b', 'x', 'aaabbbxxx_']
添加回答
举报