【问题标题】:Perl regex replacement string special variablePerl 正则表达式替换字符串特殊变量
【发布时间】:2010-12-19 02:54:00
【问题描述】:

我知道 match、prematch 和 postmatch 预定义变量。我想知道 s/// 运算符的评估替换部分是否有类似的东西。

这在动态表达式中特别有用,因此不必对它们进行第二次评估。

例如,我目前有 %regexs,它是各种搜索和替换字符串的哈希。

这是一个sn-p:

while (<>) {
  foreach my $key (keys %regexs) {   
    while (s/$regexs{$key}{'search'}/$regexs{$key}{'replace'}/ee) { 
      # Here I want to do something with just the replaced part 
      # without reevaluating.
    } 
  }
  print;
}

有没有方便的方法呢? Perl 似乎有很多方便的快捷方式,而且必须评估两次似乎是一种浪费(这似乎是另一种选择)。

编辑:我只是想举个例子:$regexs{$key}{'replace'} 可能是字符串 '"$2$1"' 从而交换了一些文本在字符串 $regexs{$key}{'search'} 可能是 '(foo)(bar)' - 从而导致 "barfoo"。我试图避免的第二个评估是 $regexs{$key}{'replace'} 的输出。

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    您可以定义代码引用来完成这项工作,而不是使用字符串eval(我认为这是s///ee 的情况)。然后这些代码引用可以返回替换文本的值。例如:

    use strict;
    use warnings;
    
    my %regex = (
        digits  => sub {
            my $r;
            return unless $_[0] =~ s/(\d)(\d)_/$r = $2.$1/e;
            return $r;
        },
    );
    
    while (<DATA>){
        for my $k (keys %regex){
            while ( my $replacement_text = $regex{$k}->($_) ){
                print $replacement_text, "\n";
            }
        }
        print;
    }
    
    __END__
    12_ab_78_gh_
    34_cd_78_yz_
    

    【讨论】:

      【解决方案2】:

      我很确定没有任何直接的方法可以满足您的要求,但这并不意味着它是不可能的。这个怎么样?

      {
        my $capture;
        sub capture {
          $capture = $_[0] if @_;
          $capture;
        }
      }
      
      while (s<$regexes{$key}{search}>
              <"capture('" . $regexes{$key}{replace}) . "')">eeg) {
        my $replacement = capture();
        #...
      }
      

      好吧,除了要真正正确地执行此操作外,您还必须在其中塞入更多代码,以使散列中的值在单引号字符串(反斜杠单引号和反斜杠)内安全。

      【讨论】:

        【解决方案3】:

        如果您手动执行第二次评估,您可以自己存储结果。

        my $store;
        s{$search}{ $store = eval $replace }e;
        

        【讨论】:

        • 最后一个 $store 是多余的; assignment 返回分配的值。
        • 啊,真的。也是多余的。
        【解决方案4】:

        为什么之前不分配给本地变量:

        my $replace = $regexs{$key}{'replace'};
        

        现在你评估一次。

        【讨论】:

        • 谢谢,但我的问题可能不清楚。我正在使用 /ee 修饰符来评估 $regexs{$key}{'replace'} 的评估结果,这可能取决于 $regexs{$key}{'search'}。
        猜你喜欢
        • 2023-03-17
        • 2014-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多