为什么我的正向前瞻断言占用了字符串而没有正确匹配?

2024-10-03 00:30:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图找到字符串中的所有子字符串,并使用正则表达式打印它们的开始和结束索引

例如, 字符串='bbbcbb' sub='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的文档,据我所知,lookahead断言将通过

  1. 在位置0处,它将“bb”与“bb”匹配,后跟“b” bbbcbb
  2. 在位置1,它将匹配“bb”和“bb”,然后是“c”。bbbcbb
  3. 然后它将不匹配,直到第4位,它将匹配“bb”与“bb”,然后$。bbbcbb

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


Tags: 字符串代码importreobjectmatch断言span
2条回答

这与您的前瞻性无关,是由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'>]

正确的方法是使用groups和lookahead,如下所述:Python regex find all overlapping matches?

模式'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)

相关问题 更多 >