从源文件中删除所有注释(单行/多行)和空行[重复]
Posted
技术标签:
【中文标题】从源文件中删除所有注释(单行/多行)和空行[重复]【英文标题】:Remove all comment (single-/multi-line) & blank lines from source file [duplicate] 【发布时间】:2012-02-25 03:45:39 【问题描述】:如何从 C# 源文件中删除所有 cmets 和空行。请记住,可能存在嵌套的 cmets。一些例子:
string text = @"//not a comment"; // a comment
/* multiline
comment */ string newText = "/*not a comment*/"; // a comment
/* multiline // not a comment
/* comment */ string anotherText = "/* not a comment */ // some text here\"// not a comment"; // a comment
我们可以有比上述三个例子更复杂的来源。 有人可以建议一种正则表达式模式或其他方法来解决这个问题。我已经在互联网上浏览了很多东西,但找不到任何有用的东西。
【问题讨论】:
为什么要从源代码中删除 cmets?? @Roy Dictus:是的,通常删除 cmets 是个坏主意!这是学校的一项棘手的任务。 :) 如果你能展示你尝试过的东西会很有帮助,尽管这个想法很糟糕。 为什么投反对票?这是一个完全合法的问题,无论其用途如何。 ***.com/questions/3524317/… 【参考方案1】:要删除 cmets,请参阅 this answer。 之后,删除空行就很简单了。
【讨论】:
@nenito,我想我发布的答案有点晚了,但无论如何它可能会很有趣。 我们仍然很好奇您为什么要删除 cmets! (或者至少我是) @comecme:首先 - 很抱歉回答迟了。 cmets 降低了代码的可读性,因此当您部署代码以对 cmets 进行某种过滤时,这可能很有用,但是您可以将代码与所有 cmets 一起存储在某个存储库中(SVN、Perforce、..) 【参考方案2】:你可以使用this answer中的函数:
static string StripComments(string code)
var re = @"(@(?:""[^""]*"")+|""(?:[^""\n\\]+|\\.)*""|'(?:[^'\n\\]+|\\.)*')|//.*|/\*(?s:.*?)\*/";
return Regex.Replace(code, re, "$1");
然后删除空行。
【讨论】:
不工作。 // 在字符串中也被删除了。 @MohsenUnlimited,不是我能看到的。示例:ideone.com/PVCdm 请证明您的声明。【参考方案3】:不幸的是,在没有边缘情况的情况下,使用正则表达式确实很难可靠地做到这一点。我还没有调查很远,但您也许可以使用Visual Studio Language Services 来解析 cmets。
【讨论】:
【参考方案4】:如果你想用正则表达式识别 cmets,你真的需要使用正则表达式作为分词器。即,它识别并提取字符串中的第一件事,无论该内容是字符串文字、注释还是既不是字符串文字也不是注释的内容块。然后你抓住字符串的剩余部分并从开头拉下一个标记。
这可以帮助您解决上下文问题。如果您只是想在字符串中间查找内容,则没有好的方法可以识别特定的“注释”是否在字符串文字中——事实上,很难确定字符串文字的位置首先,因为\"
之类的东西。但是如果你总是取字符串中的第一件事,很容易说“哦,字符串以"
开头,所以直到下一个未转义的"
的所有内容都是更多的字符串。”上下文会自行处理。
所以你需要三个正则表达式:
标识从字符串开头开始的注释(//
或 /*
注释)。
标识从字符串开头开始的字符串文字。记得检查"
和@"
字符串;每个都有自己的边缘情况。
一个标识不是上述两种情况的东西,并且匹配到第一个可能是注释或字符串文字的东西。
编写实际的正则表达式模式留给读者作为练习,因为编写和测试这一切需要几个小时,而且我不愿意免费这样做。 (咧嘴笑)但这当然是可行的,如果你对正则表达式有很好的理解(或者有一个像 *** 这样的地方可以在你遇到困难时提出具体的问题)并且愿意为你的代码编写一堆自动化测试。不过,请注意最后一种(“其他任何东西”)情况——如果它后面跟着一个 "
,你想在 @
之前停止,但如果它是 @
转义关键字以用作一个标识符。
【讨论】:
【参考方案5】:另请参阅我的 C# 代码压缩项目:CSharp-Minifier
除了从代码中删除 cmets、空格和换行符之外,目前它能够压缩局部变量名称并进行其他缩小。
【讨论】:
真是很酷的东西;) 但是 GUI 使用起来不方便(好像是为了作者的目的而写的),但是创建一个包装器并不难: 我在一个小型实际应用程序(两个项目,大约 40-50 个文件)上测试了包装器,代码无需修改即可编译 @maxkoryukov 是的,GUI 已经开发为私人使用 :) 如果您愿意,您可以使用您的修改创建拉取请求。此外,使用 Roslyn 代码分析器可以解决一些问题。 我匆忙使用了你的库,目前我只有一个运行良好的要点。下次我将使用此应用程序时 - 我将向您发送一个带有小型控制台应用程序的 PR,该应用程序利用您的库;)【参考方案6】:首先,在构建RegEx
实例时,您肯定希望使用RegexOptions.SingleLine
。现在,您正在处理单行代码。
为了补充RegexOptions.SingleLine
选项的使用,您需要确保使用start and end string anchors(分别为^
和$
),对于您的具体情况,您需要常规应用于整个字符串的表达式。
我还建议分解条件并使用alternation 处理较小的情况,从更小、更易于管理的表达式构造更大的正则表达式。
最后,我知道这是作业,但是用正则表达式解析软件语言是徒劳的(它不是实际应用)。它更适合高度结构化的数据。如果您将来发现自己想做这样的事情,请使用为该语言构建的解析器(在这种情况下,我强烈推荐Roslyn)。
【讨论】:
最后一段让我迷失了......我在使用正则表达式实现我的 C# 词法分析器时没有遇到任何问题,除了剥离 cmets。我确实觉得 cmets 是该过程的一个独特部分,因为它们对必须传递给语法器的标记没有贡献。 en.wikipedia.org/wiki/Regular_language【参考方案7】:使用我的项目删除大多数 cmets。 https://github.com/SynAppsDevelopment/CommentRemover
它删除了所有整行、结束行和 XML Doc 代码 cmets,但对自述文件和源代码中解释的复杂 cmets 有一些限制。这是一个带有 WinForms 界面的 C# 解决方案。
【讨论】:
请不要只发布一些工具或库作为答案。至少在答案本身中展示how it solves the problem。 抱歉,不知道所有指南。我的编辑有帮助吗?以上是关于从源文件中删除所有注释(单行/多行)和空行[重复]的主要内容,如果未能解决你的问题,请参考以下文章