perl:捕获被替换的字符串

时间:2018-01-17 20:35:28

标签: regex perl

我的代码在类似于

的循环中
for( my $i=0; $a =~ s/<tag>(.*?)<\/tag>/sprintf("&CITE%03d;",$i)/e ; $i++ ){  
    %cite{ $i } = $1;  
    }

但不是只是整数索引,我想让散列的键实际替换为文本(占位符“&amp; CITE001;”等),而不必重做sprintf()。

我几乎可以肯定有办法做到这一点(变量类似于$&amp;等等,但也许我正在考虑vim的替换而不是perl。:)

谢谢!

3 个答案:

答案 0 :(得分:0)

document.getElementById("fname")
    .addEventListener(`onfocus`, () => console.log(`hi`) );

答案 1 :(得分:0)

我做了一件哈克,但真的想要一些更优雅的东西。我最终做的(现在)是

my $t;  
for( my $i=0; $t = sprintf("&CITE%04d;",$i), $all =~ s/($oct.*?$cct)/$t/s; $i++ ){  
    $cites{$t} = $1;  
    }

但我真的想要一些更“自足”的东​​西。

只是能够抓住替换字符串会使事情变得更简单。这是一个简单的读 - 修改 - 写操作。

是的,添加'g'修饰符应该有助于减少它的微秒。 :d

答案 2 :(得分:0)

我认为除了从目标开始重新开始搜索之外的任何方法
总是 是更好的选择。

在这种情况下,作为替代方案,您可以在正则表达式内移动逻辑 通过代码构造 (?{ code })并利用$^N包含的事实 最后的捕获内容。

Perl

use strict;
use warnings;

use Data::Dumper;
$Data::Dumper::Sortkeys = 1;

my $target = "<tag>zero</tag>\n<tag>one</tag>\n<tag>two</tag>\n<tag>three</tag>";

my %cite;
my ($cnt,$key) = (0,'');

$target =~ s/
    <tag> (.*?) <\/tag>
    (?{
      $key = sprintf("&CITE%03d;", $cnt++);
      $cite{$key} = $^N;
    })
  /$key/xg;

print $target, "\n";

print Dumper(\%cite);

输出

&CITE000;
&CITE001;
&CITE002;
&CITE003;
$VAR1 = {
          '&CITE000;' => 'zero',
          '&CITE001;' => 'one',
          '&CITE002;' => 'two',
          '&CITE003;' => 'three'
        };

由@Ikegami编辑/编码

use strict;
use warnings;

use Data::Dumper;
$Data::Dumper::Sortkeys = 1;

sub f {
    my $target = "<tag>zero</tag>\n<tag>one</tag>\n<tag>two</tag>\n<tag>three</tag>";

    my %cite;
    my ($cnt,$key) = (0,'');

    $target =~ s/
        <tag> (.*?) <\/tag>
        (?{
          $key = sprintf("&CITE%03d;", $cnt++);
          $cite{$key} = $^N;
        })
      /$key/xg;

    print $target, "\n";

    print Dumper(\%cite);
}

f() for 1..2;

输出

Variable "$key" will not stay shared at (re_eval 1) line 2.
Variable "$cnt" will not stay shared at (re_eval 1) line 2.
Variable "%cite" will not stay shared at (re_eval 1) line 3.
&CITE000;
&CITE001;
&CITE002;
&CITE003;
$VAR1 = {
          '&CITE000;' => 'zero',
          '&CITE001;' => 'one',
          '&CITE002;' => 'two',
          '&CITE003;' => 'three'
        };




$VAR1 = {};

此问题已在5.18中解决。

Perl @sln

请参阅,现在我在版本5.20中没有得到该问题 并且,我不相信我也在5.12中得到它。

use strict;
use warnings;

use Data::Dumper;
$Data::Dumper::Sortkeys = 1;

sub wrapper {
   my ($targ, $href) = @_;
   my ($cnt, $key) = (0,'');
   $$targ =~ s/<tag>(.*?)<\/tag>(?{ $key = sprintf("&CITE%03d;", $cnt++); $href->{$key} = $^N; })/$key/g;
}

my ($target,%cite) = ("<tag>zero</tag>\n<tag>one</tag>\n<tag>two</tag>\n<tag>three</tag>", ());
wrapper( \$target, \%cite );
print $target, "\n";
print Dumper(\%cite);

($target,%cite) = ("<tag>zero</tag>\n<tag>one</tag>\n<tag>two</tag>\n<tag>three</tag>", ());
wrapper( \$target, \%cite );
print $target, "\n";
print Dumper(\%cite);

输出

&CITE000;
&CITE001;
&CITE002;
&CITE003;
$VAR1 = {
          '&CITE000;' => 'zero',
          '&CITE001;' => 'one',
          '&CITE002;' => 'two',
          '&CITE003;' => 'three'
        };
&CITE000;
&CITE001;
&CITE002;
&CITE003;
$VAR1 = {
          '&CITE000;' => 'zero',
          '&CITE001;' => 'one',
          '&CITE002;' => 'two',
          '&CITE003;' => 'three'
        };