私はperlサブルーチンの定義を開始するperlコードと一致するようにperlで正規表現を書いています。ここに私の正規表現はあります:Perlの正規表現は貪欲ではありません
my $regex = '\s*sub\s+([a-zA-Z_]\w*)(\s*#.*\n)*\s*\{';
$ regexは、サブルーチンを開始するコードにマッチします。私は$ 1のサブルーチンの名前と、$ 2のサブルーチン名と初期の中括弧の間の空白とコメントを取得しようとしています。それは私に問題を与えている2ドルです。
は、次のPerlコードを考えてみましょう:私は、文字列の中に、このPerlのコードを入れて、$の正規表現に対してそれを一致
my $x = 1;
sub zz
# This is comment 1.
# This is comment 2.
# This is comment 3.
{
$x = 2;
return;
}
は、$ 2があるが、ない三行「#これはコメント3 \ nは」私が欲しいコメントの私は正規表現が貪欲にコメントの3行すべてを$ 2にすると思ったが、それはそうではないようだ。
$ regexが動作しない理由と、簡単な置き換えを設計する理由を理解したいと思います。以下のプログラムが示すように、私はより複雑な置換え($ re3)を持っています。しかし、なぜ私は$ regexが動作しないのかを理解することが重要だと思います。
use strict;
use English;
my $code_string = <<END_CODE;
my \$x = 1;
sub zz
# This is comment 1.
# This is comment 2.
# This is comment 3.
{
\$x = 2;
return;
}
END_CODE
my $re1 = '\s*sub\s+([a-zA-Z_]\w*)(\s*#.*\n)*\s*\{';
my $re2 = '\s*sub\s+([a-zA-Z_]\w*)(\s*#.*\n){0,}\s*\{';
my $re3 = '\s*sub\s+([a-zA-Z_]\w*)((\s*#.*\n)+)?\s*\{';
print "\$code_string is '$code_string'\n";
if ($code_string =~ /$re1/) {print "For '$re1', \$2 is '$2'\n";}
if ($code_string =~ /$re2/) {print "For '$re2', \$2 is '$2'\n";}
if ($code_string =~ /$re3/) {print "For '$re3', \$2 is '$2'\n";}
exit 0;
__END__
上記のperlスクリプトの出力は次のようになります。
$code_string is 'my $x = 1;
sub zz
# This is comment 1.
# This is comment 2.
# This is comment 3.
{
$x = 2;
return;
} # sub zz
'
For '\s*sub\s+([a-zA-Z_]\w*)(\s*#.*\n)*\s*\{', $2 is '# This is comment 3.
'
For '\s*sub\s+([a-zA-Z_]\w*)(\s*#.*\n){0,}\s*\{', $2 is '# This is comment 3.
'
For '\s*sub\s+([a-zA-Z_]\w*)((\s*#.*\n)+)?\s*\{', $2 is '
# This is comment 1.
# This is comment 2.
# This is comment 3.
'
['PPI'](http://search.cpan.org/perldoc?PPI)も参照してください。 '$ subs = PPI :: Document-> new(\ $ code_string) - > find( 'PPI :: Statement :: Sub'); ... – mob