Я пишу регулярное выражение в 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 - это "# Это комментарий 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.
'