如何从代码中删除 C 风格的注释

3
我刚刚在SO上读到一个新问题,基本上与我的标题中的问题相同。这让我思考并搜索了网络(大多数结果当然指向SO ;))。所以我想 -
应该有一个简单的正则表达式能够从任何代码中删除C风格的注释。
是的,在SO上有关于这个问题/陈述的答案,但我发现它们都不完整和/或过于复杂。
所以我开始尝试,并想出了一个可以处理我所想象的所有类型代码的正则表达式:
(?:\/\/(?:\\\n|[^\n])*\n)|(?:\/\*(?:\n|\r|.)*?\*\/)|(("|')(?:\\\\|\\\2|\\\n|[^\2])*?\2)

第一个选择项检查双斜杠//注释。第二个选择项用于普通注释/* comment */。第三个选择项是我发现其他正则表达式处理相同任务时遇到困难的部分 - 包含字符序列的字符串,在字符串外部被视为注释内容。

此部分的作用是捕获任何字符串到捕获组一中,与捕获组二中的引号匹配的引用字符串,一直匹配到字符串末尾。

应该在替换中保留捕获组一,丢弃所有内容(替换为""),从而保留未注释的代码:)。

这里是regex101上的C示例。

好的...所以那不是你认为的问题。那是一个答案......

是的,你说得对。所以......进入问题。

我有没有漏掉任何类型的代码,这个正则表达式会错过?

它可以处理

多行注释

/*
    an easy one
*/

"

行末注释

"
// Remove this

字符串中的注释

char array[] = "Following isn't a comment // because it's in a string /* this neither */";

这导致了具有转义引号的字符串

    char array[] = "Handle /* comments */ - // - in strings with \" escaped quotes";

和带有转义字符的字符串

    char array[] = "Handle strings with **not** escaped quotes\\"; // <-EOS

JavaScript 单引号字符串

var myStr = 'Should also ignore enclosed // comments /* like these */ ';

行继续

// This is a single line comment \
continuing on the next row (warns, but works in my C++ flavor)

那么,你能想到任何可能会破坏这个的代码案例吗?如果你能想到,我会尝试完成RE并希望它最终是完整的;)

问候。

附言。我知道...在右窗格下面的提问方式中写道:我们更喜欢可以回答的问题,而不仅仅是讨论。 这个问题可能违反了这个规定:S,但我无法抵制。

事实上,对一些人来说,它甚至可能成为一个答案,而不是一个问题。(太自大了?;)


2
有几个问题:(?:\n|\r|.)*? 应该被替换为类似 [\s\S]*? 的东西(最好的方法是使用展开循环技术来展开它),而 [^\2] 匹配除了 \2 以外的任何字符(不是反向引用!) - Wiktor Stribiżew
2
由多个字符组成的字符常量:int a = '//'; - chux - Reinstate Monica
2
你似乎没有处理三字符序列 :) - SergeyA
1
C++11的原始字符串字面量:R"x("/**/)x" - Biffen
8
我强烈反对声称“应该有一个简单的正则表达式能够从任何代码中删除C风格的注释”。我不明白为什么会有这样的假设。此外,候选正则表达式并不支持这个命题,并且正如观察到的那样,它甚至无法涵盖所有情况。 - John Bollinger
显示剩余11条评论
1个回答

2

我已经考虑了评论(到目前为止),并将正则表达式更改为:

(?:\/\/(?:\\\n|[^\n])*\n)|(?:\/\*[\s\S]*?\*\/)|((?:R"([^(\\\s]{0,16})\([^)]*\)\2")|(?:@"[^"]*?")|(?:"(?:\?\?'|\\\\|\\"|\\\n|[^"])*?")|(?:'(?:\\\\|\\'|\\\n|[^'])*?'))

它处理Biffens C++11的原始字符串字面量(以及C#的逐字字符串),并根据Wiktors的建议进行了更改。

将其拆分为单引号和双引号分别处理,因为逻辑上存在差异(并避免非工作反向引用;)。

毫无疑问,它更加复杂,但仍然远非我在其他解决方案中看到的那些,这些解决方案几乎不涵盖任何字符串问题。而且它可以剥离对特定语言不适用的部分。

有评论建议支持更多语言。这将使RE(更加)复杂且难以管理。不过它应该相对容易进行调整。

更新的regex101示例

感谢大家迄今为止的意见。请继续提出建议。

敬礼

编辑:更新原始字符串 - 这次我实际阅读了规范。 ;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接