如何使用Python re.sub基于列表变量按序替换正则匹配内容
问题
在Python 3环境下使用re.sub方法时,能否通过列表指定待插入值,基于同一正则匹配模式向字符串中插入不同的对应值?
具体需求示例如下:
初始测试代码:
line = "Float: __, string: __" values = ["float", "string"] newLine = re.sub('(_+)([.]_+)?', (lambda m: f'%' f'{len(m.group(1))}' f'{"." if values == "float" else ""}' f'{(len(m.group(2) or ".")-1) if values == "float" else ""}' f'{"f" if values == "float" else "s"}'), line) print(newLine)
- 预期输出结果:
Float: %2.0f, string: %2s
- 实际运行输出结果:
Float: %2s, string: %2s
尝试遍历values列表获取正确结果时,代码运行失败抛出TypeError异常,尝试编写的代码如下:
newLine = re.sub('(_+)([.]_+)?', ((lambda m: f'%' f'{len(m.group(1))}' f'{"." if v == "float" else ""}' f'{(len(m.group(2) or ".")-1) if v == "float" else ""}' f'{"f" if v == "float" else "s"}') for v in values), line)
补充说明:values列表的长度与正则匹配到的模式数量始终相等。
问题原因
- 第一版代码判断条件写为
values == "float",此处values是完整列表对象,不可能等于字符串"float",因此所有匹配项都走else分支,全部返回s格式符。 - 第二版代码传入生成器作为
re.sub的替换参数,而re.sub的替换参数仅接受字符串或单参数可调用对象(入参为匹配结果对象,返回值为替换字符串),传入生成器会直接触发类型错误。
正确实现
既然已经保证values长度和匹配到的占位符数量完全一致,最简单的实现方式是把values转成迭代器,每次匹配时按顺序取下一个值做判断即可:
import re line = "Float: __, string: __" values = ["float", "string"] val_iter = iter(values) newLine = re.sub( r'(_+)([.]_+)?', lambda m: ( f'%{len(m.group(1))}.{len(m.group(2) or ".")-1}f' if next(val_iter) == "float" else f'%{len(m.group(1))}s' ), line ) print(newLine)
运行后直接输出预期结果:
Float: %2.0f, string: %2s
内容的提问来源于stack exchange,提问作者jrn6270
相关产品推荐
相关产品推荐

