首页 > 解决方案 > 为什么我的积极前瞻断言会消耗字符串并且不正确匹配?

问题描述

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

例如, string = '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上的文档,据我了解,前瞻断言将通过

  1. 在位置 0,它将匹配 'bb' 与 "bb" 后跟 "b" .ie bb bcbb
  2. 在位置 1,它将匹配 'bb' 与 "bb" 后跟 "c" .ie b bb cbb
  3. 然后它将不匹配,直到位置 4 它将匹配 'bb' 与 "bb" 后跟 $ .ie bbbc bb

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

标签: pythonregexpython-3.x

解决方案


该模式'bb(?=[a-zA-Z]|$)将匹配 2 个字符而不是 1 个,断言右侧是字符 az 或字符串的结尾。

使用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)

推荐阅读