re.sub - 多值和多行替换

时间:2015-05-17 11:51:00

标签: python regex python-2.7

假设我们的文件in.conf包含文字:

line1 = %var1%
line2 = %var2%
line3 = %var3%

我们有脚本,必须替换%var(s)%中的所有in.conf并生成新文件 - out.conf

#!/usr/bin/env python

import re

infile = 'in.conf'
outfile = 'out.conf'

change_vars_list = ('%var1%', '%var2%', '%var3%')
change_values_list = ('newvalue1', 'newvalue2', 'newvalue3')

with open(infile, 'r') as inconf:
    lines = inconf.read()

    print('\nRaw lines:\n\n%s' % lines)
    print('\nVars to change:')
    print(change_vars_list)

    outdata = re.sub(r'%var1%', 'NEWVALUE', lines)
    print('\nNew data:\n\n%s\n' % outdata)

with open(outfile, 'w') as outconf:
    outconf.write(outdata)

虽然re.sub只需要%var1%,但效果非常好:

$ ./replace.py

Raw lines:

line1 = %var1%
line2 = %var2%
line3 = %var3%


Vars to change:
('%var1%', '%var2%', '%var3%')

New data:

line1 = NEWVALUE
line2 = %var2%
line3 = %var3%

$ cat out.conf
line1 = NEWVALUE
line2 = %var2%
line3 = %var3%

但是 - 我怎么知道,同一个脚本可以用来自%var(s)%的给定值替换所有change_values_list并将它们保存到新文件out.conf

所以 - out.conf必须如下:

line1 = newvalue1
line2 = newvalue2
line3 = newvalue3

4 个答案:

答案 0 :(得分:1)

编辑初始代码:

#!/usr/bin/env python

import re

infile = 'in.conf'
outfile = 'out.conf'

change_vars_list = (r'%var1%', r'%var2%', r'%var3%')
change_values_list = ('newvalue1', 'newvalue2', 'newvalue3')

with open(infile, 'r') as inconf:
    lines = inconf.read()

    print('\nRaw lines:\n\n%s' % lines)
    print('\nVars to change:')
    print(change_vars_list)

    outdata = lines
    for var, value in zip(change_vars_list, change_values_list):
        outdata = re.sub(var, value, outdata)

    print('\nNew data:\n\n%s\n' % outdata)

with open(outfile, 'w') as outconf:
    outconf.write(outdata)

或者,如果它总是简单的替换,你可以使用replace字符串函数:

for var, value in zip(change_vars_list, change_values_list):
    outdata = outdata.replace(var, value)

答案 1 :(得分:0)

不确定这是最好的解决方案 - 但它确实有效:

#!/usr/bin/env python

infile = 'in.conf'
outfile = 'out.conf'

change_vars_list = ('%var1%', '%var2%', '%var3%')
change_values_list = ('newvalue1', 'newvalue2', 'newvalue3')

with open(outfile, 'r+') as outconf:
    with open (infile, 'r') as inconf:
            for line, var, value in zip(inconf, change_vars_list, change_values_list):
                print('Var %s value %s' % (var, value))
                outconf.write(line.replace(var, value))

$ ./replace.py
Var %var1% value newvalue1
Var %var2% value newvalue2
Var %var3% value newvalue3

$ cat out.conf
line1 = newvalue1
line2 = newvalue2
line3 = newvalue3

但仍然希望有其他想法...

答案 2 :(得分:0)

尝试:

outdata = re.sub(r'%var[0-9]%', 'NEWVALUE', lines)

re.sub的第一个参数是正则表达式模式。你会找到一个有用的备忘单,可以测试你的模式here

答案 3 :(得分:0)

解决核心问题,因为您已经处理好文件了:

template = 'line1 = %var1%\nline2 = %var2%\nline3 = %var3%'
change_vars_list = ('%var1%', '%var2%', '%var3%')
change_values_list = ('newvalue1', 'newvalue2', 'newvalue3')
changes = dict(zip(change_vars_list, change_values_list))
import re
print(re.sub('|'.join(changes),
             lambda match: changes[match.group()],
             template))

打印:

line1 = newvalue1
line2 = newvalue2
line3 = newvalue3

除非你有充分的理由分别指定change_vars_listchange_values_list,否则我会这样写:

template = 'line1 = %var1%\nline2 = %var2%\nline3 = %var3%'
changes = {'%var1%': 'newvalue1',
           '%var2%': 'newvalue2',
           '%var3%': 'newvalue3'}
import re
print(re.sub('|'.join(changes),
             lambda match: changes[match.group()],
             template))

或者,如果您不坚持使用正则表达式:

template = 'line1 = %var1%\nline2 = %var2%\nline3 = %var3%'
change_vars_list = ('%var1%', '%var2%', '%var3%')
change_values_list = ('newvalue1', 'newvalue2', 'newvalue3')
for var, value in zip(change_vars_list, change_values_list):
    template = template.replace(var, value)
print(template)

或者再缩短一次:

template = 'line1 = %var1%\nline2 = %var2%\nline3 = %var3%'
changes = (('%var1%', 'newvalue1'),
           ('%var2%', 'newvalue2'),
           ('%var3%', 'newvalue3'))
for var, value in changes:
    template = template.replace(var, value)
print(template)