Подстановка Python с функцией замены

У меня есть файл с некоторым 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 ( перед номером и запятой после номера в обработке строк).