2015-11-25 3 views
0

У меня есть дамп nodata sql, и мне нужно пройти его и заменить часть ядра каждого запроса на создание таблицы. Дело в том, где я застрял в том, что мне нужно указать имя таблицы в каждой строке я заменяю с для соответствующей таблицыЗаменить все вхождения строки регулярного выражения с информацией из ввода + строки

Предполагая, что файл, как показано ниже

CREATE TABLE `tablename1` (
    -- #columns and keys 
) ENGINE=InnoDB AUTO_INCREMENT=5075 DEFAULT CHARSET=utf8; 
CREATE TABLE `tablename2` (
    -- #columns and keys 
) ENGINE=something AUTO_INCREMENT=55 DEFAULT CHARSET=latin1; 

Желаемого результата:

CREATE TABLE `tablename1` (
    -- #columns and keys 
) ENGINE=-myreplacedstring/tablename1; -- #table name 1 is appended to this line 
CREATE TABLE `tablename2` (
    -- #columns and keys 
) ENGINE=myreplacedstring/tablename2; -- #table name 2 is appended to this line 

Я попытался

fin = open('dump.sql','r') 
filedata = fin.read() 
fin.close() 

newdata = re.sub('(?<=ENGINE).*;', '-myreplacedstring-', filedata) 

fout = open('fed_dump.sql','w') 
fout.write(newdata) 
fout.close() 

, но это только заменяет строку с фиксированным строка, независимо от того, какая таблица она есть.

Я также пытался приблизиться к строке за строкой, чтобы иметь возможность захватить имя таблицы каждый раз, когда я ее передаю, но я не уверен, как это сделать.

with open('dump.sql') as infile, open('dump_fed.sql', 'w') as outfile: 
    for line in infile: 
     #tablename= if line contains create table, update tablename, else do nothing 
     line = re.sub('(?<=ENGINE).*;', '-myreplacedstring-'+tablename, line) 
     outfile.write(line) 

Я застрял на том, как получить имя таблицы для каждой таблицы в мою замененную строку. Любая помощь приветствуется.

+0

Если вы читаете весь файл как одну строку (если она небольшая), я предлагаю захватить все подстроки между 'CREATE TABLE' и') ENGINE = 'в некоторые * table_block * s (вы можете использовать это регулярное выражение -' CREATE \ s + TABLE \ s + \ '[^ \ '] * \' \ s + \ ([^)] * (?: \) (?! \ s + ENGINE =) [^)]) * \) \ s + ENGINE = . * '([demo here] (https://regex101.com/r/aF3iP6/1)), а затем используйте' re.sub (r "\ bENGINE \ b. *", "ENGINE-myreplacedstring-", table_block) '. –

+0

Проблема, с которой я сталкиваюсь, заключается в том, что добавление tablename добавлено в конец myreplacedstring для каждой таблицы. – AdrianBR

ответ

1

Ваше решение, безусловно, будет работать, но вы можете сделать это быстрее с обратными ссылками. Я испытал это, и он работает (вы можете сделать его Однострочник но подмигнули более читаемым таким образом):

pattern = r"CREATE TABLE `(.*?)`(.*?)ENGINE=.*?;" 
replace_pattern = r"CREATE TABLE `\1`\2ENGINE=-myreplacedstring-\1;" 
newdata = re.sub(pattern, replace_pattern, filedata, flags=re.DOTALL) 

С: '. *?

  • , который является не жадный версия '. *'
  • '\ 1'является обратной ссылкой для первой группы захвата для каждого вхождения, который будет, например, «tablename1», «tablename2» и так далее
  • узоров как сырая строка с prefix'r' (что является хорошей привычкой к )
  • флаг re.DOTALL, который позволяет «.». чтобы соответствовать новой строке

я предложил до следующего решения, которое является неправильным, потому что смотреть-задом, сигнализируется «(< = ...?)», должен содержать фиксированные паттерны длины:

pattern = r"(?<=CREATE TABLE `(.*?)`.*?ENGINE=).*;" 
newdata = re.sub(pattern, '-myreplacedstring-\1', filedata) 
+0

Должно быть, я делаю это неправильно, я попробовал, но получил ошибку. Http://pastebin.com/i6k27B6a – AdrianBR

+0

Действительно, я забыл, позади должна быть фиксированная длина, и поэтому мы не можем использовать в ней «*», эта ошибка является законной.Мы можем обойти это, взяв неизвестную группу за пределы внешнего вида и добавив ее снова в заменяющую строку, я отредактирую свой ответ. – Enaid

+0

Работает как шарм, спасибо за возвращение! – AdrianBR

0

Выяснил это. Не уверен, насколько это изящно или нерушимо, но, похоже, он отлично работает для моего случая (принимая дамп mysql nodata, заменяя движок объединенной строкой соединения, чтобы легко создать полную федеративную БД с одного db на другой).

import re 

def gettablename(string, defaultstring): 
    if 'CREATE TABLE' in string: 
     return re.search('`(.*)`', string).group(1) 
    else: 
     return defaultstring 

with open('dump.sql') as infile: 
    tablename='def' # do i need this default? 
    for line in infile: 
     tablename=gettablename(line,tablename) 
     line = re.sub('(?<=ENGINE).*;', '-myreplacedstring-'+tablename, line) 
     print line