如何找到与正则表达式重叠的匹配?

fut*_*110 62 python regex overlapping

>>> match = re.findall(r'\w\w', 'hello')
>>> print match
['he', 'll']
Run Code Online (Sandbox Code Playgroud)

因为\ w\w意味着两个字符,'他'和'll'是预期的.但为什么'el'和'lo' 与正则表达式匹配?

>>> match1 = re.findall(r'el', 'hello')
>>> print match1
['el']
>>>
Run Code Online (Sandbox Code Playgroud)

Ott*_*ger 91

findall默认情况下不会产生重叠匹配.但是这个表达式确实:

>>> re.findall(r'(?=(\w\w))', 'hello')
['he', 'el', 'll', 'lo']
Run Code Online (Sandbox Code Playgroud)

(?=...)是一个先行断言:

(?=...)匹配如果...匹配下一个,但不消耗任何字符串.这称为先行断言.例如, 只有在其后跟时才Isaac (?=Asimov)匹配.'Isaac ''Asimov'

  • 但我不明白为什么它会前进到下一个字母,如果它位于积极的前瞻断言内。请你解释一下好吗? (4认同)
  • @MrZH6我猜这是由于组捕获(大括号\w\w)。实际的匹配仍然是一个空字符串,而第 1 组由 \w\w 填充(您可以在 https://regex101.com/ 进行测试)。所以我相信它在一个组中捕获它,但不会前进超过它,因为匹配是零长度。python 的 re.findall 将打印捕获的组 https://docs.python.org/3/library/re.html#re.findall (2认同)

Dav*_*d C 31

您可以使用支持重叠匹配的新Python regex模块.

>>> import regex as re
>>> match = re.findall(r'\w\w', 'hello', overlapped=True)
>>> print match
['he', 'el', 'll', 'lo']
Run Code Online (Sandbox Code Playgroud)


nha*_*tdh 10

除零长度断言外,输入中的字符将始终在匹配中消耗.如果你曾经想要在输入字符串中捕获某些字符,那么在正则表达式中你将需要零长度断言.

有几个零长度断言(例如^(输入/线的开始),$(输入/线的结束),\b(字边界)),但是环顾((?<=)正面后视和(?=)正向前瞻)是唯一的方法您可以从输入中捕获重叠文本.负面观察((?<!)负面观察,(?!)负面预测)在这里不是很有用:如果它们断言为真,则内部捕获失败; 如果他们断言错误,则匹配失败.这些断言是零长度的(如前所述),这意味着它们将在不消耗输入字符串中的字符的情况下断言.如果断言通过,它们实际上将匹配空字符串.

应用上述知识,适用于您的案例的正则表达式将是:

(?=(\w\w))
Run Code Online (Sandbox Code Playgroud)