使用 Perl 正则表达式删除多行 C 样式 /* 注释 */

Posted

技术标签:

【中文标题】使用 Perl 正则表达式删除多行 C 样式 /* 注释 */【英文标题】:Remove multi-line C style /* comments */ using Perl regex 【发布时间】:2015-02-25 06:07:39 【问题描述】:

如何删除多行 C 样式的 cmets,例如:

/* comments
   comments
   comments
   comments */

我可以通过使用其他问题中提供的几个代码来删除一行中的 cmets,例如 /* comments */

s#/\*[\s\S]*?\*/##sg;
s#/\*(.*?)\*/##sg;
s#/\*[^*]*\*+([^/*][^*]*\*+)*/|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $2 ? $2 : ""#gse

以上所有三个正则表达式都不适用于多行 cmets。如何处理?

【问题讨论】:

你需要处理像/\在一行,\在下一行,* comment *\在下一行,另一行只有\,最后/ 在下一行,标记评论结束?您是否需要允许编写任何这些反斜杠 ??/ 而不是 \ 我设法删除了一行 cmets,例如 // something。但是,我不太确定您提到的反斜杠,抱歉,这里是编码新手;) 好。这是否也可以处理多行// something\ 行和下一行continuation of previous comment?如果您是这方面的新手,您可以确定这些混蛋的 cmets 超出了范围,尤其是因为任何实际编写它们的人都应该因滥用 C(或 C++、Java 或其他任何东西确实是语言)。然而,这是编译器编写者必须处理的那种废话。 @AvinashRaj:嗯,一方面,cmets 可以从一行的末尾开始并继续到后续行。此外,在某些时候,您必须担心:const char c_start[] = "/*"; const char c_end[] = "*/"; 不包含任何评论。你甚至可以拥有像int c1 = '/*'; int c2 = '*/'; 这样不包含任何cmets 的不可移植代码。彻底完成这项工作绝对不是微不足道的。然而,这类事情很可能超出了 OP 需要处理的范围,他可以感谢他的幸运星,他没有制作商业级的评论删除器。 答案在常见问题解答中:perldoc.perl.org/…? 【参考方案1】:

我愿意,

perl -0777pe 's/\/\*(?:(?!\*\/).)*\*\/\n?//sg' file

例子:

$ cat fi
/* comments
   comments
   comments
   comments */
bar
$ perl -0777pe 's/\/\*(?:(?!\*\/).)*\*\/\n?//sg' fi
bar

【讨论】:

如果我在命令窗口中键入它,单行就可以工作。但是,我应该打开一个文本文件并删除其中的 cmets。 s/\/\*(?:(?!\*\/).)*\*\/\n?//sg foreach (@lines) 删除单行 cmets,但不删除多行 cmets。有什么想法吗? 我认为 foreach 循环一次只能获取一行。 为什么要使用段落模式-00?你的意思是使用啜饮模式-0777 是的,如果/**/ 之间有空行,00pe 将不起作用 现在我看到了我的问题所在!有没有办法在不使用foreach/for的情况下删除cmets时逐行检查文件?

以上是关于使用 Perl 正则表达式删除多行 C 样式 /* 注释 */的主要内容,如果未能解决你的问题,请参考以下文章

perl正则表达式怎么匹配多行?

Perl正则表达式匹配多行文件与匹配变量如何处理换行

Perl 正则表达式多行匹配没有点

perl 正则表达式 匹配多行的问题

使用正则表达式解析 C 样式注释,避免回溯

perl多个正则表达式匹配多行