Regex 如何从Perl脚本中除去shebang行之外的所有注释?

Regex 如何从Perl脚本中除去shebang行之外的所有注释?,regex,perl,Regex,Perl,我有一个从其他Perl脚本中删除注释的Perl脚本: open (INFILE, $file); @data = <INFILE>; foreach $data (@data) { $data =~ s/#.*/ /g; print "$data"; } 除了shebang之外,我如何剥离注释?编写代码剥离注释并不简单,因为#字符可以用于注释以外的其他上下文。改用: 将从文件foo中剥离#注释(但不是POD),并将输出写入foo.tdy。舍邦并没有被剥夺。如果它不

我有一个从其他Perl脚本中删除注释的Perl脚本:

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

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

除了shebang之外,我如何剥离注释?

编写代码剥离注释并不简单,因为
#
字符可以用于注释以外的其他上下文。改用:

将从文件
foo
中剥离
#
注释(但不是POD),并将输出写入
foo.tdy
。舍邦并没有被剥夺。如果它不是一个练习的话,那么它就是这样做的方法。还有一个用于解析perl的方法。可以使用
PPI::Token::Comment
Token做一些比剥离更复杂的事情

然而,要回答您的直接问题,不要试图在一个正则表达式中解决所有问题。相反,把你的问题分解成信息和逻辑的逻辑片段。在这种情况下,如果要跳过第一行,请使用逐行处理,它可以方便地在
$
中设置当前行号

use strict;
use warnings;
use autodie;

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

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

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

    print;
}
使用严格;
使用警告;
使用自动模具;
我的$file='。。。你的档案;

打开我的$fh,“因为您要求使用正则表达式解决方案:

'' =~ /(?{
   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;
}
有一种方法可以使用:

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;


您只需创建一个名为
$skip
的变量,其值为
1
。在代码第一次进入循环时,如果
$skip
等于1,则将该值更改为0,然后
继续
。您的代码还将剥离类似
$#array
的代码,这不是一个评论。谢谢你,先生,但我真的想跳过第一个事件,而不是第一行。@tidibur shebang不能在第一行之外的任何其他行上。那么事情进展如何?你有没有告诉你的老师他是个笨蛋@蒂迪布尔和我想要一匹小马。正则表达式不能胜任这项任务,你在浪费时间去尝试。由于字符串引用等原因,您甚至不能用正则表达式可靠地处理琐碎的情况。@tidibr然后您将不得不编写一个正则表达式来解释可以使用
的所有不同上下文:块注释(
#foo
),边注释(
my$foo;#foo
),字符串(
my$foo=''foo'
my$foo=q/\foo/;
等等),这里是文档、数组(
my$last=$\array;
),等等。不要重新发明轮子(很糟糕)。@ThisSuitesBlacknot我试图用它跳过第一次出现:
foreach$data(@data){$data=~s/\35;(?!!\/)///g;print“$data”}
虽然我能够保存路径,使其不被删除,但以下事件仅删除了“#”而不是整个注释。@tidibur这是一个无用的考试,由一个不懂Perl的老师创建。这个问题非常复杂,充满了边缘案例。即使像你这样一个微不足道的正则表达式对Perl代码也会造成极大的破坏。你必须限制注释的样式,例如
/^#/
(首先是行,然后是空格)。但即使这样也可能以无数种方式失败,例如多行字符串或正则表达式。告诉你的老师,他会被打动。或者被侮辱,但嘿,yolo。@tidibur,ThisSuitisBlack不是指“复杂”是指“页面和页面长”我同意TLP的观点。不管是谁写的考试都犯了一个错误。我可以告诉你,不能处理shebang行是不能接受的,但不能处理
$\array
“是可以接受的。”
s#/##
第1000行
,等等。你的程序将无法在你自己的程序上运行!除了破坏
$#数组
“#”
s#/#g
第1000行等明显的问题外,它不会删除第一行的注释(如果有的话)。我应该这么说“除了一个明显的问题,即程序本身不起作用“!@Miller代码简短但清晰。做得很好,但如果将shebang放在第二行,这将不起作用。尽管这是一个纯粹的常识,它应该永远是第一位。我会尝试一下。谢谢you@tidbur,你错了。第二行上不可能有shebang这样的东西。根据定义,shebang(
#!
)必须是文件的前两个字符。我的解决方案不是“解决方案”。它的意思是建议一种处理此问题的方法,但您肯定需要添加更多的逻辑。无论如何,请不要这样做,因为我只是想向您的讲师显然有意的方向做一点提示。感谢您的帮助,但这种方法太复杂,我无法理解。我只学习了大约一周的perl。它确实可以事实上,如果第一行和最后一行都不存在,这与此相同:它运行perltidy,并抛出和报告任何错误。您坚持它必须在正则表达式中,所以就这样做了。如果您不理解这一点,您怎么可能编写Perl解析器呢?是的。很抱歉。我希望@miller的解决方案足够了。谢谢您的努力。:)@Miller的解决方案在Miller的解决方案上不起作用。我尝试了它,但它起作用了。但只有当“shebang”在第一行时..hmmm看起来不错,但是当我在一个文件中循环时,在一个变量中有字符串时,我该如何使用它呢?你可以试着在该变量上运行
PPR::decomment()
?对不起,唠叨(作为非perl程序员)但是如果说字符串在
$cleanline
中,我该怎么做呢?没问题。你试过
PPR::docomment($cleanline)
吗?我刚发了一条唠叨的评论,然后我看到了
$res
行,所以我只想写评论:哦,愚蠢的我,只是
我的$res=PPR::decomment($cleanline);
。测试需要一些时间,我可能必须安装PPR
#!/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";
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{}#]/;