我正在研究一个例程,以从某些C#代码中删除块 或 行注释。我看了网站上的其他示例,但没有找到我想要的 确切 答案。
我可以将此正则表达式与RegexOptions.Singleline完全匹配块注释(/ * comment * /):
(/\*[\w\W]*\*/)
我可以使用带有RegexOptions.Multiline的正则表达式来整体匹配行注释(// comment):
(//((?!\*/).)*)(?!\*/)[^\r\n]
注意:我使用的[^\r\n]不是,$因为$也包括\r在比赛中。
[^\r\n]
$
\r
然而,这并不 十分 工作,我希望它的方式。
这是我要匹配的测试代码:
// remove whole line comments bool broken = false; // remove partial line comments if (broken == true) { return "BROKEN"; } /* remove block comments else { return "FIXED"; } // do not remove nested comments */ bool working = !broken; return "NO COMMENT";
块表达式匹配
/* remove block comments else { return "FIXED"; } // do not remove nested comments */
很好,但是行表达式匹配
// remove whole line comments // remove partial line comments
和
// do not remove nested comments
另外,如果我两次没有在行表达式中使用* /正向查找,它将与
// do not remove nested comments *
我 真的 不想要
我要的是将匹配字符,从与表达//,到行的末尾,但 不 包含*/之间//和行尾。
//
*/
另外,只是为了满足我的好奇心,有人可以解释为什么我需要两次超前吗? (//((?!\*/).)*)[^\r\n]并且(//(.)*)(?!\*/)[^\r\n]都将包括*,但(//((?!\*/).)*)(?!\*/)[^\r\n]并(//((?!\*/).)*(?!\*/))[^\r\n]不会。
(//((?!\*/).)*)[^\r\n]
(//(.)*)(?!\*/)[^\r\n]
(//((?!\*/).)*(?!\*/))[^\r\n]
您的两个正则表达式(用于块和行注释)均存在错误。如果您愿意,我可以描述一下这些bug,但是我觉得如果编写新的bug可能会更有效率,尤其是因为我打算编写一个同时匹配两者的bug。
问题是,每次你有时间/*和//和文字字符串“干扰”互相,它始终是一个开始:第一,优先。这非常方便,因为这正是正则表达式的工作方式:首先找到第一个匹配项。
/*
因此,让我们定义一个与这四个标记匹配的正则表达式:
var blockComments = @"/\*(.*?)\*/"; var lineComments = @"//(.*?)\r?\n"; var strings = @"""((\\[^\n]|[^""\n])*)"""; var verbatimStrings = @"@(""[^""]*"")+";
要回答标题中的问题(带状注释),我们需要:
Regex.Replace 可以使用MatchEvaluator函数轻松做到这一点:
Regex.Replace
string noComments = Regex.Replace(input, blockComments + "|" + lineComments + "|" + strings + "|" + verbatimStrings, me => { if (me.Value.StartsWith("/*") || me.Value.StartsWith("//")) return me.Value.StartsWith("//") ? Environment.NewLine : ""; // Keep the literal strings return me.Value; }, RegexOptions.Singleline);
我在Holystream提供的所有示例以及我能想到的其他各种情况下运行了这段代码,它的工作原理很吸引人。如果您可以提供一个失败的示例,我们很乐意为您调整代码。