我有一个包含数据库所有create语句的模式文件,我想将它们拆分以获得每个单独的语句:
CREATE TABLE leads (
id integer PRIMARY KEY,
first_name text NOT NULL,
email text NOT NULL
);
CREATE TABLE lead_logs (
id INTEGER PRIMARY KEY,
old_id int,
new_id int,
old_email text,
new_email text
);
CREATE TRIGGER validate_email_before_insert_leads
BEFORE INSERT ON leads
BEGIN
SELECT
CASE
WHEN NEW.email NOT LIKE '%_@__%.__%' THEN
RAISE (ABORT,'Invalid email address')
END;
END;
CREATE TRIGGER log_contact_after_update
AFTER UPDATE ON leads
WHEN old.phone <> new.phone
OR old.email <> new.email
BEGIN
INSERT INTO lead_logs VALUES(
old.id,
new.id,
old.email,
new.email
);
END;
我可以在上拆分文本当我只有CREATE TABLE
语句时,但现在我还有CREATE TRIGGER
和BEGIN
和END
命令,它们也有分号,我需要一种更智能的方法来提取完整的语句。
由于每个语句都以CREATE
开头,在接下来的CREATE
之前以;n
结束,我认为我可以使用DOTALL
标志编译(CREATE.*;)nCREATE
,这样换行符就被点考虑在内,但python的re.findall
只返回一个单个提取,其中包含除最后一条语句外的所有内容。
我认为它可能与子组有关,但((CREATE.*;)n)*
只返回空字符串,CREATE.*;n
将返回整个原始文本。
我可以使用python简单地在CREATE
序列前面加上其他东西并进行拆分,但这似乎相当原始:
txt.replace('CREATE', 'OOGABOOGA-CREATE').split('OOGABOOGA-')
我确信这在regex中非常简单,但我无法理解它,有人能帮我一把吗?
如果您坚持使用正则表达式,请使用语法为?
的非贪婪正则表达式,以避免获得完整的原始文本。并查找以;
结尾且没有前导空格的行。只有当数据的格式与示例类似时,它才有效。
print([s[0] for s in re.findall('(CREATE[sS]+?(n[^ ]+;))', sql)])
输出:
['CREATE TABLE leads (n id integer PRIMARY KEY,n first_name text NOT NULL,n email text NOT NULLn);',
'CREATE TABLE lead_logs (n id INTEGER PRIMARY KEY,n old_id int,n new_id int,n old_email text,n new_email textn);',
"CREATE TRIGGER validate_email_before_insert_leads n BEFORE INSERT ON leadsnBEGINn SELECTn CASEn WHEN NEW.email NOT LIKE '%_@__%.__%' THENn RAISE (ABORT,'Invalid email address')n END;nEND;",
'CREATE TRIGGER log_contact_after_update n AFTER UPDATE ON leadsn WHEN old.phone <> new.phonen OR old.email <> new.emailnBEGINn INSERT INTO lead_logs VALUES(n old.id,n new.id,n old.email,n new.emailn );nEND;']