我有以下正则表达式:
Regex defineProcedureRegex = new Regex(@"\s*(\bcreate\b\s+\bprocedure\b\s+(?:|dbo\.))(\w+)\s+(?:|(.+?))(as\s+(?:.+?)\s+\bgo\b)\s*", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.RightToLeft | RegexOptions.Singleline);
我正在针对包含多个“create procedure”语句的SQL脚本文件运行。文件的格式如下:
use databasename
create procedure dbo.procedure_name
@param1 varchar(10) -- optional
as
-- do stuff
go
use databasename
create procedure dbo.another_procedure
@param1 varchar(10) -- optional
as
-- do other stuff
go
我遇到的问题是我需要匹配第一个as
,但只匹配最后一个go
。由于程序正文还可能包含as
和go
(在评论中),我无法弄清楚如何可靠地执行此操作。
任何帮助/意见/建议?
答案 0 :(得分:2)
由于程序正文也可能包含as和go(在注释中)
(在字符串文字和标识符中,是)。
你必须进行贪婪的比赛,直到go
。但是,这将从源中的第一个存储过程的开始到最后一个的结束匹配!
您可以使用否定匹配来确保贪婪匹配不会超过“创建过程”边界:
(as\s+(?:(?!create\s+procedure).)+?\s+\bgo\b)
然而,这仍然不是水密的,因为您可能在评论或字符串文字中有create procedure
。
结论:正则表达式是解析复杂的非常规语言(如SQL)的不充分工具。您将需要一个适当的SQL解析器。这不是一项简单的工作。见例如。 this question
答案 1 :(得分:0)
试试这个:
create procedure (?<schema>.*?)\.(?<name>\w+)(?<params>[\s\S]*?)?as[\s\S]*?go
注意我使用的是非贪婪模式,即*?