Python如何获取正则表达式重叠匹配模式的所有替换结果
实现正则所有重叠匹配的全量替换结果获取
Python 标准库的re.sub默认在匹配到重叠结果时,只会替换最左侧的首个匹配项,不会遍历所有重叠匹配生成替换结果,可以通过遍历全量匹配项单独替换的方式实现需求,同时完全兼容原生re的所有替换规则(包括捕获组反向引用等复杂场景)。
问题复现
常规替换写法:
import re re.sub(pattern='III', repl='U', string='MIIII')
默认仅返回MUI,但实际字符串MIIII中III存在两个重叠匹配位置,对应两个合法替换结果:
MUI MIU
方案需要兼容复杂正则替换逻辑,例如下方带捕获组的替换,原生返回结果为MIUIU,自定义实现也需要保持相同的替换行为:
re.sub(pattern="M(.*)$", repl="M\\1\\1", string='MIU') # 输出结果:MIUIU
实现代码
直接用re.finditer扫描字符串中所有匹配项(包括重叠位置的匹配),再调用匹配对象自带的expand方法处理替换逻辑,完全复用re模块原生的替换规则解析能力,不需要自己实现反向引用、转义符处理逻辑:
import re from typing import List def all_re_sub_results(pattern: str, repl: str, content: str) -> List[str]: res = set() for match in re.finditer(pattern, content): # 原生expand方法和re.sub的repl解析逻辑完全一致 replaced = match.expand(repl) full_replaced = content[:match.start()] + replaced + content[match.end():] res.add(full_replaced) return list(res)
验证效果
- 重叠匹配场景测试
print(all_re_sub_results(pattern='III', repl='U', content='MIIII')) # 输出 ['MUI', 'MIU']
- 带捕获组的复杂正则场景测试
print(all_re_sub_results(pattern="M(.*)$", repl="M\\1\\1", content='MIU')) # 输出 ['MIUIU']
说明
- 用set存储结果是为了自动去重,避免不同位置匹配替换后生成相同字符串的重复返回问题
- 所有替换逻辑完全复用re模块原生实现,和原生
re.sub单匹配替换的行为完全一致,支持所有正则语法、命名分组、反向引用、转义字符等特性 - 如果需要按匹配从左到右的顺序返回结果,可以把结果存储改为列表,按匹配顺序收集即可
内容的提问来源于stack exchange,提问作者Paul_0
相关产品推荐
相关产品推荐

