Python中如何获取互相重叠的多词正则全部匹配结果
重叠正则匹配结果获取方案
问题说明
待处理测试文本:
for more cynicism and polarization in our politics now there're no quick fixes to this long-term trend i agree our trade should be fair and not just free but the next wave of economic dislocations won't come from overseas it will come from the relentless pace of automation that makes a lot of good middle class jobs obsolete and so we're going to have to forge a new social compact to guarantee all our kids the
匹配规则要求:
- 核心匹配目标为符合正则
\b(com(es?|ing)|came)\b的单词 - 每个匹配结果需要包含核心词前后各3个单词
- 预期输出2个重叠的结果:
economic dislocations won't come from overseas itoverseas it will come from the relentless
初始编写的正则为:
\w+'?\w*\s\w+'?\w*\s\w+'?\w*\s\b(com(es?|ing)|came)\b\s\w+'?\w*\s\w+'?\w*\s\w+'?\w*
该正则无法拿到重叠结果的核心原因:常规正则匹配默认会消费已匹配的字符,第一次匹配完成后,匹配指针会直接跳到第一次匹配结果的末尾,不会回溯扫描重叠区域,因此会漏掉相邻的重叠匹配项。
可行解决方法
方法1:零宽断言改造正则(单正则实现)
使用正向前瞻零宽断言包裹原有匹配规则,零宽断言不会消费字符,匹配完成后指针仅向后移动1个字符,可覆盖所有重叠位置。改造后的正则如下:
(?=((?:\w+'?\w*\s+){3}\b(?:com(?:es?|ing)|came)\b(?:\s+\w+'?\w*){3}))
使用注意事项:
- 所有符合要求的匹配结果都存储在第1个捕获组中,不要直接取正则整体匹配值(零宽断言本身匹配的是空字符串)
- 该方法在支持PCRE、JavaScript、Python re等主流正则引擎的环境中均可正常运行
方法2:拆分匹配步骤(兼容性最优)
如果使用的正则引擎对零宽断言内捕获支持不佳,可拆分逻辑实现,完全规避字符消费问题,步骤如下:
- 用核心匹配正则
\b(com(es?|ing)|came)\b全局扫描文本,拿到所有核心匹配词的位置索引 - 对每一个核心匹配项,单独向前截取3个单词、向后截取3个单词,拼接为最终结果片段
该方法逻辑稳定,不受匹配项间距、重叠程度影响,适配所有支持正则的环境。
内容的提问来源于stack exchange,提问作者south662
相关产品推荐
相关产品推荐

