我有一个包含一些 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)
但这只是输出递增的值而不是进行替换。我做错了什么?
最佳答案
将您的正则表达式更改为:
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 (
和数字后面的逗号。
关于Python 使用替换函数进行替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22930722/