【问题标题】:Regex expression to split SQL create statements用于拆分 SQL 创建语句的正则表达式
【发布时间】:2021-12-12 00:02:33
【问题描述】:

我有一个架构文件,其中包含我的数据库的所有创建语句,我想将它们拆分以获取每个单独的语句:

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 TRIGGERBEGINEND 命令,这也得到一个分号,我需要一种更智能的方法来提取完整​​的语句。

由于每个语句都以CREATE 开头并在以下CREATE 之前以;\n 结尾,我虽然可以使用DOTALL 标志编译(CREATE.*;)\nCREATE,因此换行符由点考虑,但python 的@ 987654331@ 仅返回包含除最后一条语句之外的所有内容的单个提取

虽然它可能与子组有关,但((CREATE.*;)\n)* 仅返回空字符串CREATE.*;\n 将返回整个原始文本

我可以使用 python 简单地在 CREATE 序列前面加上其他东西并拆分,但这似乎相当原始:

txt.replace('CREATE', 'OOGABOOGA-CREATE').split('OOGABOOGA-')

我确定这在正则表达式中非常简单,但我无法理解它,有人可以帮我吗?

【问题讨论】:

  • 使用 split() 分割起始文本上的记录。
  • 拆分单词CREATE - split("CREATE") - 然后将单词CREATE 添加到结果中。也许它是有前途的,但它可以工作,并且可能对于长字符串它可以比regex 更快地工作

标签: python regex


【解决方案1】:

如果您坚持使用正则表达式,请使用 non-greedy 正则表达式? 语法以避免获取整个原始文本。并查找以 ; 结尾且没有前导空格的行。它仅在您的数据按照您的示例进行格式化时才有效。

print([s[0] for s in re.findall('(CREATE[\s\S]+?(\n[^ ]+;))', sql)])

输出

['CREATE TABLE leads (\n    id integer PRIMARY KEY,\n    first_name text NOT NULL,\n    email text NOT NULL\n);',
 'CREATE TABLE lead_logs (\n    id INTEGER PRIMARY KEY,\n    old_id int,\n    new_id int,\n    old_email text,\n    new_email text\n);',
 "CREATE TRIGGER validate_email_before_insert_leads \n   BEFORE INSERT ON leads\nBEGIN\n   SELECT\n      CASE\n    WHEN NEW.email NOT LIKE '%_@__%.__%' THEN\n      RAISE (ABORT,'Invalid email address')\n       END;\nEND;",
 'CREATE TRIGGER log_contact_after_update \n   AFTER UPDATE ON leads\n   WHEN old.phone <> new.phone\n        OR old.email <> new.email\nBEGIN\n    INSERT INTO lead_logs VALUES(\n        old.id,\n        new.id,\n        old.email,\n        new.email\n    );\nEND;']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-01
    • 2012-04-30
    相关资源
    最近更新 更多