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

Posted

技术标签:

【中文标题】如何从代码中删除 C 风格的注释【英文标题】:How to remove C-style comments from code 【发布时间】:2016-07-27 00:42:40 【问题描述】:

我刚刚在这里阅读了一个关于 SO 的新问题,该问题与我在标题中所做的基本相同。这让我开始思考 - 并搜索网络(当然,大多数点击都指向 SO ;)。所以我想-

应该有一个简单的正则表达式能够从任何代码中删除 C 风格的 cmets。

是的,有关于 SO 的这个问题/陈述的答案,但我发现的答案都是不完整和/或过于复杂的。

所以我开始试验,并想出了一个适用于所有类型的代码可以想象:

(?:\/\/(?:\\\n|[^\n])*\n)|(?:\/\*(?:\n|\r|.)*?\*\/)|(("|')(?:\\\\|\\\2|\\\n|[^\2])*?\2)

第一个替代检查 双斜杠 // cmets。第二个用于普通 /* comment */。第三个是我很难找到处理相同任务处理的其他正则表达式 - 包含字符串之外的字符序列的字符串,将被视为 cmets

这部分的作用是捕获捕获组 1 中的任何字符串,匹配捕获组 2 中的引号符号,匹配引用符号,直到字符串的末尾。

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

Here's a C example at regex101.

好的...所以这不是问题。这是你认为的答案......

是的,你是对的。所以...关于这个问题。

我是否遗漏了该正则表达式会遗漏的任何类型的代码?

它处理

多行cmets

/*
    an easy one
*/

“行尾”cmets

// Remove this

字符串中的cmets

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 并希望它最终完成 em> ;)

问候。

PS。我知道...在右侧窗格中,如何提问下写着这个:我们更喜欢可以回答的问题,而不仅仅是讨论。这个问题可能违反了:S 但我无法抗拒。

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

【问题讨论】:

有几个问题:(?:\n|\r|.)*? 应该替换为 [\s\S]*? 之类的东西(最好的方法是使用展开循环技术展开它)并且[^\2] 匹配任何字符,但 \2(不是反向引用!) 由多个字符组成的字符常量:int a = '//'; 你似乎没有处理三元组 :) C++11 的原始字符串文字:R"x("/**/)x" 我非常不同意“应该有一个简单的正则表达式能够从任何代码中删除 C 风格的 cmets”的断言。我不明白为什么有人会这么认为。此外,候选正则表达式不支持该命题,并且正如已经观察到的那样,它即使这样也不能涵盖所有情况。 【参考方案1】:

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

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

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

由于逻辑上的差异,将其拆分为分别处理单引号和双引号(并避免无效的反向引用;)。

毫无疑问,它更复杂,但与我所看到的几乎没有字符串问题的解决方案相去甚远。并且可以去掉不适用于特定语言的部分。

一条评论建议支持更多语言。这将使 RE(甚至更加)复杂且难以管理。不过应该比较容易适应。

Updated regex101 example.

感谢大家迄今为止的投入。并不断提出建议。

问候

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

【讨论】:

以上是关于如何从代码中删除 C 风格的注释的主要内容,如果未能解决你的问题,请参考以下文章

如何在Eclipse中如何自动添加注释和自定义注释风格

如何从 python 源代码中删除注释和文档字符串? [关闭]

SQL/Regex Challenge/Puzzle:如何从 SQL 代码中删除注释(通过使用 SQL 查询)?

如何进行CodeReview

项目代码风格要求

C中#if 0 和#if 1 详解