使用正则表达式删除文本块,仅匹配第一次出现

时间:2015-04-24 22:09:38

标签: c# regex

我需要使用正则表达式从生成的脚本中删除存储过程。例如,我需要删除usp_Remove:

...
GO
/****** Object:  StoredProcedure [dbo].[usp_Remove] ******/
...
GO
/****** Object:  StoredProcedure [dbo].[usp_Keep]  ******/
...
GO

我尝试了以下正则表达式:

\/*\*\*\*\*\*\* Object:  StoredProcedure \[dbo\]\.\[usp_Remove\][\s\S]*GO

正确选择文本的开头。但它匹配所有内容直到最后一个“GO”,我需要它匹配,直到第一次出现“GO”,以便只删除该存储过程。任何帮助将不胜感激!

4 个答案:

答案 0 :(得分:1)

我会使用延迟匹配以免过度匹配,并使用正向预测来仅捕获存储过程:

(?si)/\*{6}\s+Object:\s+StoredProcedure\s+\[dbo\]\.\[usp_Remove\]\s+\*{6}\/.*?(?=GO)

示例代码:

var txt = "YOUR_TXT";
var rx = new Regex(@"/\*{6}\s+Object:\s+StoredProcedure\s+\[dbo\]\.\[usp_Remove\]\s+\*{6}\/.*?(?=GO)", RegexOptions.Singleline | RegexOptions.Ignorecase);
var result = rx.Replace(txt, string.Empty);

快报:

enter image description here

答案 1 :(得分:0)

这是一个模式,它使用Multiline的Regex Options(指定^将在行的开头)和Singleline,告诉.包含空白字符:

string text = @"...
GO
/****** Object:  StoredProcedure [dbo].[usp_Remove] ******/
...
GO
/****** Object:  StoredProcedure [dbo].[usp_Keep]  ******/
...
GO";

Console.WriteLine (Regex.Replace(text,
                                 @"(^\/.+usp_Remove.+?GO)",
                                 string.Empty,
                                 RegexOptions.Multiline | RegexOptions.Singleline ));

结果是

... 
GO

/****** Object:  StoredProcedure [dbo].[usp_Keep]  ******/ 
... 
GO

答案 2 :(得分:0)

你可能想试试这个:

string resultString = null;
try {
    resultString = Regex.Replace(subjectString, @"\/.*?\[usp_Remove\].*?$\s+GO", "", RegexOptions.Singleline | RegexOptions.Multiline);
} catch (ArgumentException ex) {
    // Syntax error in the regular expression
}

输出:

...
GO

/****** Object:  StoredProcedure [dbo].[usp_Keep]  ******/
...
GO

DEMO

正则表达式解释:

\/.*?\[usp_Remove\].*?$\s+GO

Options: Case sensitive; Exact spacing; Dot matches line breaks; ^$ match at line breaks; Numbered capture

Match the character “/” literally «\/»
Match any single character «.*?»
   Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Match the character “[” literally «\[»
Match the character string “usp_Remove” literally (case sensitive) «usp_Remove»
Match the character “]” literally «\]»
Match any single character «.*?»
   Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Assert position at the end of a line (at the end of the string or before a line break character) (line feed) «$»
Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s+»
   Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match the character string “GO” literally (case sensitive) «GO»

答案 3 :(得分:0)

这是GREEDY正则表达式模式的产物。 请查看此内容以获取更多信息:http://stackoverflow.com/a/5319978/4408842

我决定只添加一个负面预测((?! GO)),以确保没有其他" GO"区块内的陈述" / ... ..."和" GO"。 请记住,你要取出的SQL脚本块不能有另一个" GO"声明本身,或者这种方法将停止在那个" GO"

我还重写了您的 [\ s \ S] * 限定符 - 这是一个贪婪的限定符,可以查找任意数量的空格或非空白字符(含义) ,在找到模式结束之前尽可能多的事情,并且我已经将 \ * \ * \ * \ * \ * \ * 重写为 \ * { 6} 以便于阅读。

\/\*{6} Object:  StoredProcedure \[dbo\]\.\[usp_Remove\].{0,10}\*{6}\/(?!GO)[.\n]*GO

RegexHero