Perl:将子例程传递给正则表达式替换搜索结果

4

i have the following perl subroutine:

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)
}

and the following text:

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 (...)识别为搜索和替换的结果?


5
你做错了什么?首先,你没有使用strict和warnings,而且你的“perl”看起来像是1999年的版本。 - innaM
3
妈妈,对不起,我会尽量不再这样做。 - user2141046
3
你还不够好,去你的房间! - Jimbo
1个回答

7
我不确定在正则表达式中替换部分能否以所需方式设置而不使用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)
}

嗯,mpapec,这个可以运行(我还在努力弄清楚怎么做... :-) )。 - user2141046
第一个还是第二个例子?两者都使用了匿名函数,也被称为回调函数。 - mpapec
刚刚检查了第二个,它也可以工作(实际上 - 我更喜欢它!)。非常感谢。 - user2141046

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接