问题:
谁能给我一个可以从 SQL 语句中删除单行注释的有效正则表达式 (C#/VB.NET)?
我的意思是这些评论:
-- This is a comment
不是那些
/* this is a comment */
因为我已经可以处理明星评论了。
我做了一个小解析器,当这些注释位于行首时,它会删除它们,但它们也可能位于代码之后的某个地方,或更糟糕的是,在 SQL 字符串中'hello --Test -- World'
这些注释也应该被删除(当然除了 SQL 字符串中的注释 - 如果可能的话)。
令人惊讶的是我没有让正则表达式工作。我本以为明星评论会更难,但实际上并非如此。
根据请求,这里是我删除 /**/ 风格注释的代码
(为了让它忽略 SQL 样式字符串,您必须用唯一标识符替换字符串(我使用了 4 个串联),然后应用注释删除,然后应用字符串反向替换。
static string RemoveCstyleComments(string strInput)
{
string strPattern = @"/[*][\w\d\s]+[*]/";
//strPattern = @"/\*.*?\*/"; // Doesn't work
//strPattern = "/\\*.*?\\*/"; // Doesn't work
//strPattern = @"/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/ "; // Doesn't work
//strPattern = @"/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/ "; // Doesn't work
// http://stackoverflow.com/questions/462843/improving-fixing-a-regex-for-c-style-block-comments
strPattern = @"/\*(?>(?:(?>[^*]+)|\*(?!/))*)\*/"; // Works !
string strOutput = System.Text.RegularExpressions.Regex.Replace(strInput, strPattern, string.Empty, System.Text.RegularExpressions.RegexOptions.Multiline);
Console.WriteLine(strOutput);
return strOutput;
} // End Function RemoveCstyleComments
我会让你们所有人失望的。这不能用正则表达式来完成。当然,很容易找到不在字符串中的注释(即使是OP也可以做到),真正的问题是字符串中的注释。还有一点点希望环顾四周,但这还不够。告诉你一行中有前面的引用并不能保证任何事情。唯一能保证你有所收获的是引用的奇怪之处。一些你用正则表达式找不到的东西。因此,只需采用非正则表达式方法即可。
EDIT:这是 C# 代码:
String sql = "--this is a test\r\nselect stuff where substaff like '--this comment should stay' --this should be removed\r\n";
char[] quotes = { '\'', '"'};
int newCommentLiteral, lastCommentLiteral = 0;
while ((newCommentLiteral = sql.IndexOf("--", lastCommentLiteral)) != -1)
{
int countQuotes = sql.Substring(lastCommentLiteral, newCommentLiteral - lastCommentLiteral).Split(quotes).Length - 1;
if (countQuotes % 2 == 0) //this is a comment, since there's an even number of quotes preceding
{
int eol = sql.IndexOf("\r\n") + 2;
if (eol == -1)
eol = sql.Length; //no more newline, meaning end of the string
sql = sql.Remove(newCommentLiteral, eol - newCommentLiteral);
lastCommentLiteral = newCommentLiteral;
}
else //this is within a string, find string ending and moving to it
{
int singleQuote = sql.IndexOf("'", newCommentLiteral);
if (singleQuote == -1)
singleQuote = sql.Length;
int doubleQuote = sql.IndexOf('"', newCommentLiteral);
if (doubleQuote == -1)
doubleQuote = sql.Length;
lastCommentLiteral = Math.Min(singleQuote, doubleQuote) + 1;
//instead of finding the end of the string you could simply do += 2 but the program will become slightly slower
}
}
Console.WriteLine(sql);
它的作用是:找到每条评论的字面意思。对于每个内容,通过计算当前匹配项和最后一个匹配项之间的引号数来检查它是否在评论中。如果这个数字是偶数,那么它是一个注释,因此将其删除(找到行的第一个结尾并删除之间的内容)。如果它是奇数,则它在字符串内,找到字符串的末尾并移动到它。 Rgis 片段基于一个奇怪的 SQL 技巧:“this”是一个有效的字符串。即使两个报价不同。如果您的 SQL 语言不适合,您应该尝试完全不同的方法。如果是这样的话,我也会为此编写一个程序,但这个程序更快、更简单。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)