如何使用Perl从文件中删除多行C注释?

任何人都可以使用正则表达式来删除文件中的多行注释和单行注释吗?

例如:

" WHOLE "/*...*/" HAS TO BE STRIPED OFF....." 1. /* comment */ 2. /* comment1 */ code /* comment2 */ #both /*comment1*/ and /*comment2*/ #has to striped off and rest should #remain. 3. /*......... ......... ......... ......... */ 

如果你有这个需要,我真的很感激你….提前感谢。

包括测试:

 use strict; use warnings; use Test::More qw(no_plan); sub strip_comments { my $string=shift; $string =~ s#/\*.*?\*/##sg; #strip multiline C comments return $string; } is(strip_comments('a/* comment1 */ code /* comment2 */b'),'a code b'); is(strip_comments('a/* comment1 /* comment2 */b'),'ab'); is(strip_comments("a/* comment1\n\ncomment */ code /* comment2 */b"),'a code b'); 

从perlfaq6 “如何使用正则表达式从文件中删除C样式注释?”:


虽然这实际上可以做到,但它比你想象的要困难得多。 例如,这个单线

 perl -0777 -pe 's{/\*.*?\*/}{}gs' foo.c 

将在许多但不是所有情况下工作。 你知道,对于某些类型的C程序来说,它太简单了,特别是那些带有引号字符串注释的程序。 为此,你需要这样的东西,由Jeffrey Friedl创建,后来由Fred Curtis修改。

 $/ = undef; $_ = <>; s#/\*[^*]*\*+([^/*][^*]*\*+)*/|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $2 ? $2 : ""#gse; print; 

当然,这可以用/ x修饰符更清晰地编写,添加空格和注释。 Fred Curtis礼貌地扩展了它。

 s{ /\* ## Start of /* ... */ comment [^*]*\*+ ## Non-* followed by 1-or-more *'s ( [^/*][^*]*\*+ )* ## 0-or-more things which don't start with / ## but do end with '*' / ## End of /* ... */ comment | ## OR various things which aren't comments: ( " ## Start of " ... " string ( \\. ## Escaped char | ## OR [^"\\] ## Non "\ )* " ## End of " ... " string | ## OR ' ## Start of ' ... ' string ( \\. ## Escaped char | ## OR [^'\\] ## Non '\ )* ' ## End of ' ... ' string | ## OR . ## Anything other char [^/"'\\]* ## Chars which doesn't start a comment, string or escape ) }{defined $2 ? $2 : ""}gxse; 

稍作修改也会删除C ++注释,可能使用延续字符跨越多行:

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

和Perl一样,你可以达到CPAN: Regexp :: Common :: Comment应该可以帮到你。 我发现使用你所描述的评论的一种语言是Nickle,但也许PHP评论可以(//也可以开始单行评论)。

请注意,在任何情况下,使用正则表达式删除注释都很危险,语言的完整解析器风险要小得多。 例如,regexp-parser可能会被print "/*";类的东西搞糊涂print "/*";

这是一个FAQ:

 perldoc -q comment 

在perlfaq6中找到:

如何使用正则表达式从文件中删除C样式注释?

虽然这实际上可以做到,但它比你想象的要困难得多。 例如,这个单线…

还有一个非perl答案:使用程序stripcmt :

StripCmt是一个用C编写的简单实用程序,用于从C,C ++和Java源文件中删除注释。 在Unix文本处理程序的传统中,它可以作为FIFO(先进先出)filter或在命令行上接受参数。

删除/ * * /注释(包括多行)

 s/\/\*.*?\*\///gs 

我发布这个因为它很简单,但我相信它会绊倒嵌入式评论

 /* sdafsdfsdf /*sda asd*/ asdsdf */ 

但由于它们相当罕见,我更喜欢简单的正则表达式。