如何使用Python同时替换文本行中的多个指定元素
问题:批量替换文本中的指定元素
需求
将文本文件中所有出现在listSWMM列表内的元素,统一替换为03_元素名格式(例如C1替换为03_C1),要求能同时替换同一行内的多个目标元素。
原始数据
文本文件(CONDUITS.txt)内容:
C1 NJ_03_PKL_0354 SU1 4.138 0.013 1014.67 1014.658 0 0 C2 NJ_03_DRG_0079 MS_03_DRN_0369 10 0.013 1014.45 1014.658 0 0 C3 NJ_03_DRG_0078 MS_03_DRN_0369 4.359 0.013 1014.48 1014.658 0 0 C4 NJ_03_DRG_0076 MS_03_DRN_0369 10 0.013 1014.67 1014.658 0 0 C5 NJ_03_PKL_0355 SU2 10 0.013 1032.66 1032.76 0 0 C6 MS_03_QLD_0352 MS_03_QLD_0419 35.662 0.015 1018.68 1018.4 0 0 C7 MS_03_QLD_0217 SU4 28.438 0.015 1019.75 1019.111 0 0 C8 MS_03_FPK_0042 NJ_03_FPK_0013 263.08 0.015 1001.75 999.05 0 0 MC_03_BDO_0000 MS_03_BDO_0000 MS_03_BDO_0001 53.07 0.015 1023.72 1023.33 0 0
匹配列表:
listSWMM=['J1','J2','J3', 'J4', 'J5', 'J6', 'J7', 'J8', 'J9', 'J10', 'J11', 'J12','J13',' J14', 'J15','J16','J17', 'J18', 'J19', 'J20', 'J21', 'J22', 'J24', 'J25', 'J26', 'J27','J28',' J29','J30','SU1', 'SU2','SU3', 'SU4', 'SU5', 'SU6', 'SU7', 'SU8', 'SU9', 'SU10', 'SU11', 'SU12','SU13',' SU14', 'SU15','SU16','SU17', 'SU18', 'SU19', 'SU20', 'SU21', 'SU22', 'SU24', 'SU25', 'SU26', 'SU27','SU28',' SU29','SU30','C1', 'C2','C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'C10', 'C11', 'C12','C13',' C14', 'C15','C16','C17', 'C18', 'C19', 'C20', 'C21', 'C22', 'C24', 'C25', 'C26', 'C27','C28',' C29','C30','OR1', 'OR2','OR3', 'OR4', 'OR5', 'OR6', 'OR7', 'OR8', 'OR9', 'OR10', 'OR11', 'OR12','OR13',' OR14', 'OR15','OR16','OR17', 'OR18', 'OR19', 'OR20', 'OR21', 'OR22', 'OR24', 'OR25', 'OR26', 'OR27','OR28',' OR29','OR30','W1', 'W2','W3', 'W4', 'W5', 'W6', 'W7', 'W8', 'W9', 'W10', 'W11', 'W12','W13',' W14', 'W15','W16','W17', 'W18', 'W19', 'W20', 'W21', 'W22', 'W24', 'W25', 'W26', 'W27','W28',' W29','W30','OL1', 'OL2','OL3', 'OL4', 'OL5', 'OL6', 'OL7', 'OL8', 'OL9', 'OL10', 'OL11', 'OL12','OL13',' OL14', 'OL15','OL16','OL17', 'OL18', 'OL19', 'OL20', 'OL21', 'OL22', 'OL24', 'OL25', 'OL26', 'OL27','OL28',' OL29','OL30']
期望替换效果(第一行示例):
03_C1 NJ_03_PKL_0354 03_SU1 4.138 0.013 1014.67 1014.658 0 0
原代码问题
原代码每次循环都基于原始行进行单个元素替换,替换结果没有累积,导致同一行内多个元素无法同时替换,还会重复输出多行:
import re infile=open(r'CONDUITS.txt','r') listSWMM=['J1','J2',... # 省略完整列表] for line in infile: for item in listSWMM: if item in line: y=re.sub(item,"03_{}".format(item),line) print(y)
解决方案
方案1:累积替换结果
对每一行,先初始化变量保存当前处理后的内容,遍历列表元素时,在当前处理后的行上进行替换,最后输出最终结果:
import re listSWMM=['J1','J2',... # 省略完整列表] # 清理列表中的空格,避免匹配带空格的无效元素 listSWMM = [item.strip() for item in listSWMM] with open(r'CONDUITS.txt','r') as infile: for line in infile: processed_line = line for item in listSWMM: # 使用\b确保匹配完整单词,避免部分匹配(比如J1不会匹配J10里的J1) processed_line = re.sub(rf'\b{item}\b', f'03_{item}', processed_line) print(processed_line)
方案2:正则批量匹配(更高效)
将所有列表元素拼接成正则匹配模式,一次性完成所有替换,效率更高:
import re listSWMM=['J1','J2',... # 省略完整列表] listSWMM = [item.strip() for item in listSWMM] # 生成正则模式,匹配任意列表中的完整单词 pattern = re.compile(r'\b(' + '|'.join(re.escape(item) for item in listSWMM) + r')\b') with open(r'CONDUITS.txt','r') as infile: for line in infile: # 用回调函数生成替换内容 processed_line = pattern.sub(lambda m: f'03_{m.group(1)}', line) print(processed_line)
关键说明
- 清理列表空格:原列表存在
' J14'这类带前导空格的元素,用strip()去除后才能正确匹配文本中的目标元素。 - 单词边界
\b:确保只匹配完整的元素,避免把J10中的J1误替换成03_J1。 - 方案2更适合大列表:避免多次循环替换,一次正则匹配完成所有操作,性能更优。
内容的提问来源于stack exchange,提问作者tester
相关产品推荐
相关产品推荐

