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

Use*_*611 5 c perl comments

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

例如:

                  " 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.   /*.........
       .........
       .........
       ......... */
Run Code Online (Sandbox Code Playgroud)

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

bri*_*foy 16

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


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

perl -0777 -pe 's{/\*.*?\*/}{}gs' foo.c
Run Code Online (Sandbox Code Playgroud)

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

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

当然,这可以用/ 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;
Run Code Online (Sandbox Code Playgroud)

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

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

  • @Paul:该功能已经在Perl中.Perl是一种通用语言.我们不希望为每个出现的任务添加内置功能.这是模块的工作. (2认同)

mir*_*rod 11

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

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


Sin*_*nür 6

这是一个FAQ:

perldoc -q comment
Run Code Online (Sandbox Code Playgroud)

perlfaq6中找到:

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

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


Ale*_*nii -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');
Run Code Online (Sandbox Code Playgroud)

  • 会弄乱字符串中出现的 /* 或 */。例如,字符串“This /* string”不包含注释开头。 (3认同)
  • 除了不处理字符串中的注释字符(甚至多字符字符常量)之外,它也不处理反斜杠-换行符拼接,例如允许开头斜杠后面跟着反斜杠、换行符,然后是星号。也不处理 C++ 注释(也可以有反斜杠换行符拼接)。它不处理三字母 - 唯一相关的是“??/”,这意味着反斜杠。这有多重要取决于您的代码需要有多安全。 (2认同)
  • 用空字符串替换注释也是错误的。当token被意外拼接时,会改变代码的语义。C 标准要求在翻译阶段 3 中将注释替换为单个空格字符。 (2认同)