为什么我的肯定超前断言会占用字符串且匹配不正确?

时间:2019-07-18 07:10:40

标签: python regex python-3.x

我正在尝试查找字符串中所有子字符串的出现,并使用正则表达式打印它们的开始索引和结束索引。

例如,     字符串='bbbcbb'     子='bb' 我的输出必须为(0,1)(1,2)(4,5)。

我的代码:

import re
matches = list(re.finditer(r'bb(?=[a-zA-Z]|$)', 'bbbcbb'))

输出:

[<_sre.SRE_Match object; span=(0, 2), match='bb'>, 
<_sre.SRE_Match object;span=(4, 6), match='bb'>]

我浏览了https://docs.python.org/3/library/re.html上的文档,并且据我所知,先行断言将起作用

  1. 在位置0,它将匹配“ bb”和“ bb”,后跟“ b”。即 bb bcbb
  2. 在位置1处,它将匹配“ bb”和“ bb”,后跟“ c”。即b bb cbb
  3. 然后它将不匹配,直到位置4匹配“ bb”和“ bb”后跟$。 bbbc bb

为什么先行断言忽略(1,3)位置的b'bb'cbb?还是我对前瞻性断言的理解有缺陷?

2 个答案:

答案 0 :(得分:1)

这与您的前瞻无关,并且是由于re未返回重叠的匹配项所致。 这是一个更简单的示例:

import re

regex = re.compile("aa")
results = list(regex.finditer("aaaa"))
#  You expect to get (0, 2), (1, 3), (2, 4)
print(results)
>>> [<_sre.SRE_Match object; span=(0, 2), match='aa'>,
     <_sre.SRE_Match object; span=(2, 4), match='aa'>]

执行此操作的正确方法是使用组和提前行,如下所述:Python regex find all overlapping matches?

答案 1 :(得分:1)

'bb(?=[a-zA-Z]|$)模式将匹配2个字符,而不是1个,表示右边是字符a-z或字符串的结尾。

使用re.finditer,您可以更新模式以匹配单个b,并将单个b放在正面前瞻中:

import re
matches = list(re.finditer(r'b(?=b)', 'bbbcbb'))
for m in matches:
    print(m.span())

结果

(0, 1)
(1, 2)
(4, 5)