Python正则如何多次匹配|\d模式实现指定位置字符串替换
问题描述
现有字符串列表输入如下:
['XX=BB|3|3|1|1|PLP|KLWE|9999|9999', 'XX=BB|3|3|1|1|2|PLP|KPOK|99999|99999', '999|999|999|9999|999', ....]
处理规则如下:
- 格式为
'999|999|999|9999|999'的纯数字竖线分隔字符串保持不变 - 带
XX=BB前缀的字符串,需要将末尾符合「2位及以上连续9组成的数字段|2位及以上连续9组成的数字段」格式的内容,替换为12|21 - 已知
BB字段和后续3位非空字符段之间,存在4~6个|数字格式的分段,原有写死固定分段数量的正则无法兼容所有场景
期望输出结果:
['XX=BB|3|3|1|1|PLP|KLWE|12|21', 'XX=BB|3|3|1|1|2|PLP|KPOK|12|21', '999|999|999|9999|999'...]
解决方案
核心是通过可变长度分组匹配兼容4~6个数字段的场景,同时增加末尾锚定避免误匹配字符串中间的9序列,正则写法如下:
(?<=XX=BB(?:\|\d+){4,6}\|\S{3}\|\S{4}\|)9{2,}\|9{2,}$
正则规则说明
(?<=XX=BB(?:\|\d+){4,6}\|\S{3}\|\S{4}\|):正向后视断言,匹配前缀规则XX=BB:匹配固定开头标识,不符合该前缀的字符串(比如全9的纯数字串)不会进入替换逻辑(?:\|\d+){4,6}:非捕获分组,匹配4到6个|数字格式的分段,兼容分段数量不固定的场景\|\S{3}\|\S{4}\|:匹配后续的3位非空字段、4位非空字段加竖线分隔
9{2,}\|9{2,}:匹配两个连续的、由2位及以上9组成的数字段,中间用竖线分隔$:锚定字符串末尾,确保只替换符合规则的末尾串,不会误改字符串中间的内容
代码示例(Python)
import re input_list = ['XX=BB|3|3|1|1|PLP|KLWE|9999|9999', 'XX=BB|3|3|1|1|2|PLP|KPOK|99999|99999', '999|999|999|9999|999'] pattern = re.compile(r'(?<=XX=BB(?:\|\d+){4,6}\|\S{3}\|\S{4}\|)9{2,}\|9{2,}$') result = [pattern.sub('12|21', s) for s in input_list] print(result) # 输出:['XX=BB|3|3|1|1|PLP|KLWE|12|21', 'XX=BB|3|3|1|1|2|PLP|KPOK|12|21', '999|999|999|9999|999']
兼容提示:如果运行环境的正则引擎不支持后视断言中使用可变长度量词,可以把断言部分挪到匹配分组里,对应正则为
(XX=BB(?:\|\d+){4,6}\|\S{3}\|\S{4}\|)9{2,}\|9{2,}$,替换时保留前缀即可,替换字符串写为\112|21。
内容的提问来源于stack exchange,提问作者S.Gu
相关产品推荐
相关产品推荐

