1

更新:为了让这个问题更容易。我已经更改了字符串,现在您根本不必担心 BEGIN END。相反,我现在只有 GO 语句作为终止符。我希望我现在能从其他人那里得到一些答案

我需要编写一个正则表达式,它可以检测隐藏的 DML 语句,如 DDL 脚本(CREATE、ALTER、DROP)中的 INSERT、UPDATE、DELETE。

例子。在下面的脚本中,它应该捕获 2 个delete table5语句和最后一个insert into table3语句。但它应该忽略实际上在存储过程本身的主体中的插入语句。

如果你在这里运行这个 RegEx:http ://regexr.com?33rf3 ,你会看到我已经完成了 90%。唯一不起作用的部分是它正在进行贪婪匹配,直到最后一个 GO。我需要它在第一次 GO 时停止。我试过使用 +? 操作员使其不贪婪,但它不想工作。

delete table5 /*Regex should find this*/

GO

create proc abc
begin
    insert into table1  /*Regex should IGNORE this*/
    begin
        fake nesting here
        insert into table2 /*Regex should IGNORE this*/
    end
end

GO

delete table5 /*Regex should find this*/

GO

alter proc abc2
begin
  --no statements in this proc
end

GO

insert into table3 /*Regex should find this*/
4

1 回答 1

2

不需要 GO 语句。

        var regex1 = new Regex(@"
          (?s)
          (create|alter|drop).+?
          begin
            (?:
               (?> (?! begin | end ) .
                  | begin (?<counter>)
                  | end  (?<-counter>)
                )*
            )
            (?(counter)(?!))
          end
          "
        , RegexOptions.IgnorePatternWhitespace
        );

        var regex2 = new Regex(@"(?:insert|update|delete).+");

        var result = regex2.Matches(regex1.Replace(your_input, ""))
            .Cast<Match>()
            .Select(m => m.Value);

此代码删除所有 create/alter/drop 语句,然后查找 delete/alter/drop。我认为它可以只使用一个正则表达式来完成,但这是我现在可以建议的全部,抱歉:)

于 2013-02-20T23:11:24.947 回答