perl: проходящие подпрограммы rexexp заменяют результатами поиска
У меня есть следующая подпрограмма Perl:
sub rep {
defined ($filein = shift) || die ("no filein");
defined ($fileout = shift) || die ("no fileout");
$look = shift;
$replace = shift;
open (infile, "$filein")|| die;
open (outfile, "> $fileout")|| die;
while (<infile>) {
s/$look/$replace/g;
print outfile;
}
(close the files)
}
и следующий текст:
kuku(fred) foo(3)
kuku(barney) foo(198)
я хочу назвать это со следующими структурами:
$look = kuku\((\w+)\) foo \((\d+)\),
$replace = gaga\(($1)\) bar\(($2)\).
но когда я вызвал сабвуфер со следующим (и его вариациями), я не смог заставить его принять формат $1, $2:
&rep ($ARGV[0], $ARGV[1],
"kuku\\(\(\\w+\)\\) foo \\(\(\\d+\)\\)" ,
"gaga\\(\(\$1\)\\) bar\\(\(\$2\)\\)");
все, что я получаю, это:
gaga($1) bar($2)
gaga($1) bar($2)
Что я делаю неправильно? Как я могу заставить подпрограмму идентифицировать $1\ $2 (...) как результаты поиска и замены?
1 ответ
Решение
Я не уверен, можно ли установить подстановочную часть в регулярном выражении так, как вы хотите, без использования eval /e
так вот как бы я это написал.
qr//
параметр является реальным регулярным выражением, за которым следует обратный вызов, в котором $_[0]
является $1
rep( $ARGV[0], $ARGV[1], qr/kuku\((\w+)\) foo \((\d+)\)/, sub { "gaga($_[0]) bar($_[1])" } );
sub rep {
my ($filein, $fileout, $look, $replace) = @_;
defined $filein or die "no filein";
defined $fileout or die "no fileout";
open (my $infile, "<", $filein) or die $!;
open (my $outfile, ">", $fileout) or die $!;
while (<$infile>) {
s/$look/$replace->($1,$2)/ge;
print $outfile;
}
# (close the files)
}
Это может быть еще более упрощено, просто передавая обратный вызов, который изменит $_
,
rep( $ARGV[0], $ARGV[1], sub { s|kuku\((\w+)\) foo \((\d+)\)|gaga($1) bar($2)| } );
sub rep {
my ($filein, $fileout, $replace) = @_;
defined $filein or die "no filein";
defined $fileout or die "no fileout";
open (my $infile, "<", $filein) or die $!;
open (my $outfile, ">", $fileout) or die $!;
while (<$infile>) {
$replace->();
print $outfile;
}
# (close the files)
}