我正在用 perl 编写一个正则表达式来匹配启动 perl 子例程定义的 perl 代码。这是我的正则表达式:
my $regex = '\s*sub\s+([a-zA-Z_]\w*)(\s*#.*\n)*\s*\{';
$regex 匹配启动子例程的代码。我还试图捕获 $1 中子例程的名称以及子例程名称和 $2 中的初始左大括号之间的任何空格和注释。2美元给我带来了麻烦。
考虑以下 perl 代码:
my $x = 1;
sub zz
# This is comment 1.
# This is comment 2.
# This is comment 3.
{
$x = 2;
return;
}
当我将此 perl 代码放入字符串并将其与 $regex 匹配时,$2 是“# This is comment 3.\n”,而不是我想要的三行注释。我以为正则表达式会贪婪地将所有三行注释放入 $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.
'