使用Perl正则表达式移除多行C风格的/*注释*/

3

如何删除多行C样式注释,例如:

/* comments
   comments
   comments
   comments */

我可以使用其他问题中提供的几个代码来一行移除注释,例如/* comments */

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

所有上述三个正则表达式都无法处理多行注释。如何处理呢?

1
你是否需要处理像一行中的“/\”,下一行中的“\”,再加上下一行的“* comment *”,另一行只有“\”,最后在下一行标记注释结束的“/”这样的混乱的C语言注释?你是否需要允许任何一个反斜杠被写成“??/”而不是“\”? - Jonathan Leffler
我成功地删除了像// something这样的单行注释。然而,关于你提到的反斜杠,我不是很确定,抱歉,我是一个编程新手 ;) - double_espresso
好的。它是否也处理多行“// something\”行,并在下一行上使用“continuation of previous comment”?如果您是新手,可以决定那些混蛋式的注释超出了范围,因为任何实际编写它们的人都应该因滥用C(或C ++,或Java,或任何真正的语言)而被绞死、拉扯和四分五裂。尽管如此,这就是编译器编写者必须处理的无稽之谈。 - Jonathan Leffler
@AvinashRaj:首先,注释可以从一行的末尾开始并延续到后续行。此外,在某些情况下,您必须担心以下内容:const char c_start [] =“ / *”; const char c_end [] =“ * /”;其中不包含任何注释。您甚至可以有非便携式代码,例如int c1 =' / *'; int c2 =' * /';也不包含任何注释。彻底完成这项工作显然是非常困难的。但是,这种东西可能远远超出了OP需要处理的范围,他可以感谢自己的幸运星,因为他没有制作商业级别的注释删除器。 - Jonathan Leffler
我明白你之前的意思了。我不需要处理那些注释。我的任务只包含多行/*something*/和单行//something - double_espresso
1
答案在常见问题解答中:http://perldoc.perl.org/perlfaq6.html#How-do-I-use-a-regular-expression-to-strip-C-style-comments-from-a-file? - Toto
1个回答

5

我会这样做,

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

例子:

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

这个一行代码在命令窗口中运行是有效的。然而,我需要打开一个文本文件并删除其中的注释。s/\/\*(?:(?!\*\/).)*\*\/\n?//sg foreach (@lines) 可以删除单行注释,但无法删除多行注释。有什么想法吗? - double_espresso
我认为foreach循环每次只会获取一行。 - Avinash Raj
你为什么使用段落模式-00?你是不是想使用吞咽模式-0777 - TLP
如果在/**/之间有空行,则00pe将无法工作。 - Avinash Raj
现在我看到了我的问题所在!有没有办法在不使用foreach/for的情况下逐行检查文件并删除注释? - double_espresso
只需将整个文件读入字符串中,并在该字符串上进行替换。https://dev59.com/QHNA5IYBdhLWcg3wdtld - Avinash Raj

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