用替换函数替换Python

时间:2014-04-08 07:46:51

标签: python regex

我有一个带有一些SQL的文件:

INSERT INTO table (ID, Name) VALUES (1, 'a');
INSERT INTO table (ID, Name) VALUES (2, 'b');
...
INSERT INTO table (ID, Name) VALUES (1000, 'all');

我想在文件中将所有ID值增加1000,以获得:

INSERT INTO table (ID, Name) VALUES (1001, 'a');
INSERT INTO table (ID, Name) VALUES (1002, 'b');
...
INSERT INTO table (ID, Name) VALUES (2000, 'all');

我编写了以下Python代码

import os, re
root = r'path\to\dir'
path = os.path.join(root, 'original.sql')
new =  os.path.join(root, 'new.sql')

def increment(n, base=1000):
    return str(int(n.group(1)) + base)

with open(path) as f, open(new, 'w') as g:
    for line in f:
        line = re.sub('.*VALUES \((\d{1,4}),.*', increment, line)
        g.write(line)

但是只输出递增的值而不是替换。我做错了什么?

1 个答案:

答案 0 :(得分:2)

将正则表达式更改为:

def fix_line(n, base=1000):
    return n.group(1) + str(int(n.group(2)) + base) + n.group(3)

line = re.sub('(.*VALUES \()(\d{1,4})(,.*)', fix_line, line)

因此,如果你有line = "INSERT INTO table (ID, Name) VALUES (1001, 'a');"开始,那么在你的正则表达式替换之后你会有:

line = "INSERT INTO table (ID, Name) VALUES (2001, 'a');"

基本上,您需要在数字之前捕获数据,然后在数字之后捕获内容,并将其包含在每行的处理中。

我应该补充一点,你在正则表达式的开头和结尾都不需要.*。它也可以与line = re.sub('(VALUES \()(\d{1,4})(,)', fix_line, line)一起使用,但这次你只匹配line的一小部分,特别是VALUES (1001,然后应用你的替换函数,并保持字符串的其他部分不变。 (你的原始正则表达式匹配整行并重新生成它。)。

您也可以

def iterate_number(n, base=1000):
    return "VALUES (%d," % (int(n.group(1)) + base)

line = re.sub('VALUES \((\d{1,4}),', iterate_number, line)

只有一个匹配的组(数字),只是在数字前添加VALUES (,在字符串处理中添加数字后的逗号。