perl:传递子例程rexexp替换为搜索结果

use*_*046 3 regex parameters perl subroutine

我有以下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)
}
Run Code Online (Sandbox Code Playgroud)

以及以下文字:

kuku(fred) foo(3)
kuku(barney) foo(198)
Run Code Online (Sandbox Code Playgroud)

我想用以下结构来调用它:

$look = kuku\((\w+)\) foo \((\d+)\),
$replace = gaga\(($1)\) bar\(($2)\).
Run Code Online (Sandbox Code Playgroud)

但是当我使用以下(以及它的变体)调用sub时,我无法接受$ 1,$ 2格式:

&rep ($ARGV[0], $ARGV[1], 
    "kuku\\(\(\\w+\)\\) foo \\(\(\\d+\)\\)" , 
    "gaga\\(\(\$1\)\\) bar\\(\(\$2\)\\)");
Run Code Online (Sandbox Code Playgroud)

我得到的是:

gaga($1) bar($2)
gaga($1) bar($2)
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?如何让子程序识别$ 1\$ 2(...)作为搜索和替换的搜索结果?

Сух*_*й27 6

我不确定正则表达式中的替换部分是否可以在不使用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)
}
Run Code Online (Sandbox Code Playgroud)

通过传递可能改变的回调可以更加简化这一点$_.

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)
}
Run Code Online (Sandbox Code Playgroud)