用输入+字符串中的信息替换所有出现的正则表达式字符串
Replace all occurences of regex string with info from input+string
我有一个 sql 无数据转储,我需要检查它并替换每个创建 table 查询的引擎部分。我被卡住的地方是我需要在每个字符串中提到 table 名称,我要替换为相应的 table
假设文件如下
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()
但这只是将字符串替换为固定字符串,而不管它是哪个table。
我也试着逐行接近,以便每次通过时都能抓取 table 名称,但我不确定如何进行此操作。
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)
我不知道如何将每个 table 的 table 名称放入我替换的字符串中。感谢任何帮助。
想通了。不确定这是多么优雅或牢不可破,但它似乎适用于我的情况(采用 mysql 无数据转储,用联合连接字符串替换引擎,轻松创建从一个数据库到另一个数据库的完整联合数据库)。
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
您的解决方案肯定会奏效,但您可以使用反向引用更快地完成。我测试了这个并且它有效(你可以把它做成一行,但这样更易读):
pattern = r"CREATE TABLE `(.*?)`(.*?)ENGINE=.*?;"
replace_pattern = r"CREATE TABLE ``ENGINE=-myreplacedstring-;"
newdata = re.sub(pattern, replace_pattern, filedata, flags=re.DOTALL)
有:
- ´.*?´ 是 ´.*´
的非贪婪版本
- ´\1´ 是每次出现的第一个捕获组的反向引用,例如 "tablename1"、"tablename2" 等等
- 模式作为带有前缀“r”的原始字符串(这是一个好习惯
拿)
- 允许“.”的 re.DOTALL 标志匹配换行符
我之前提出了以下解决方案,这是错误的,因为由“(?<=...)”表示的后视必须包含固定长度的模式:
pattern = r"(?<=CREATE TABLE `(.*?)`.*?ENGINE=).*;"
newdata = re.sub(pattern, '-myreplacedstring-', filedata)
我有一个 sql 无数据转储,我需要检查它并替换每个创建 table 查询的引擎部分。我被卡住的地方是我需要在每个字符串中提到 table 名称,我要替换为相应的 table
假设文件如下
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()
但这只是将字符串替换为固定字符串,而不管它是哪个table。
我也试着逐行接近,以便每次通过时都能抓取 table 名称,但我不确定如何进行此操作。
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)
我不知道如何将每个 table 的 table 名称放入我替换的字符串中。感谢任何帮助。
想通了。不确定这是多么优雅或牢不可破,但它似乎适用于我的情况(采用 mysql 无数据转储,用联合连接字符串替换引擎,轻松创建从一个数据库到另一个数据库的完整联合数据库)。
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
您的解决方案肯定会奏效,但您可以使用反向引用更快地完成。我测试了这个并且它有效(你可以把它做成一行,但这样更易读):
pattern = r"CREATE TABLE `(.*?)`(.*?)ENGINE=.*?;"
replace_pattern = r"CREATE TABLE ``ENGINE=-myreplacedstring-;"
newdata = re.sub(pattern, replace_pattern, filedata, flags=re.DOTALL)
有:
- ´.*?´ 是 ´.*´ 的非贪婪版本
- ´\1´ 是每次出现的第一个捕获组的反向引用,例如 "tablename1"、"tablename2" 等等
- 模式作为带有前缀“r”的原始字符串(这是一个好习惯 拿)
- 允许“.”的 re.DOTALL 标志匹配换行符
我之前提出了以下解决方案,这是错误的,因为由“(?<=...)”表示的后视必须包含固定长度的模式:
pattern = r"(?<=CREATE TABLE `(.*?)`.*?ENGINE=).*;"
newdata = re.sub(pattern, '-myreplacedstring-', filedata)