如何从除了shebang线之外的Perl脚本中删除所有注释?

时间:2014-03-26 15:20:19

标签: regex perl

我有一个Perl脚本可以删除其他Perl脚本的注释:

open (INFILE, $file);
@data = <INFILE>;

foreach $data (@data)
{
    $data =~ s/#.*/ /g;
    print "$data";
}

问题是,这段代码也删除了shebang行:

#!/usr/bin/perl

除了shebang,我怎样才能删除评论?

4 个答案:

答案 0 :(得分:12)

编写剥离注释的代码并非易事,因为#字符可以在其他上下文中使用,而不仅仅是注释。请改用perltidy

perltidy --delete-block-comments --delete-side-comments foo

将从文件#中删除foo个注释(但不是POD),并将输出写入foo.tdy。 shebang没有被剥夺。

答案 1 :(得分:3)

可以使用一种方法PPR::decomment()

use strict;
use warnings;
use PPR;

my $document = <<'EOF';
print "\n###################################\n";
print '\n###################################\n';
print '\nFollowed by comment \n'; # The comment
return $function && $function !~ /^[\s{}#]/;
EOF

my $res = PPR::decomment( $document );
print $res;

输出

print "\n###################################\n";
print '\n###################################\n';
print '\nFollowed by comment \n'; 
return $function && $function !~ /^[\s{}#]/;

答案 2 :(得分:1)

因为您要求使用正则表达式解决方案:

'' =~ /(?{
   system("perltidy", "--delete-block-comments", "--delete-side-comments", $file);
   die "Can't launch perltidy: $!\n"                   if $? == -1;
   die "perltidy killed by signal ".( $? & 0x7F )."\n" if $? & 0x7F;
   die "perltidy exited with error ".( $? >> 8 )."\n"  if $? >> 8;
});

您似乎倾向于使用以下内容:

#!/usr/bin/perl
while (<>) {
   if ($. != 1) {
      s/#.*//;
   }
   print;
}

但它本身不起作用:

$ chmod u+x stripper.pl

$ stripper.pl stripper.pl >stripped_stripper.pl

$ chmod u+x stripped_stripper.pl

$ stripped_stripper.pl stripper.pl
Substitution pattern not terminated at ./stripped_stripper.pl line 4.

$ cat stripped_stripper.pl
#!/usr/bin/perl
while (<>) {
   if ($. != 1) {
      s/
   }
   print;
}

它也无法删除第一行的注释:

$ cat >first.pl
# This is my first Perl program!
print "Hello, World!\n";

$ stripper.pl first.pl
# This is my first Perl program!
print "Hello, World!\n";

答案 3 :(得分:0)

perltidy是执行此操作的方法,如果它只是一个练习。还有PPI用于解析perl。可以使用PPI::Token::Comment令牌做一些比剥离更复杂的事情。

但是,要回答您的直接问题,请不要尝试在单个正则表达式中解决所有问题。相反,将您的问题分解为逻辑信息和逻辑。相反,如果你想跳过第一行,可以使用逐行处理来方便地设置$中的当前行号。

use strict;
use warnings;
use autodie;

my $file = '... your file...';

open my $fh, '<', $file;

while (<$fh>) {
    if ($. != 1) {
        s/#.*//;
    }

    print;
}

<强>声明

使用正则表达式解决这个问题的方法肯定是有缺陷的,正如大家已经说过的那样。但是,我会给你的导师带来疑问,并且他/他的目的是通过故意给你一个超出正则表达式能力范围的问题进行教学。好好寻找所有这些边缘情况并弄清楚如何处理它们。

无论你做什么,都不要试图用一个正则表达式来解决它们。解决问题并使用大量ifelsif