代码之家  ›  专栏  ›  技术社区  ›  Charles

perl中的内联正则表达式替换

  •  10
  • Charles  · 技术社区  · 14 年前

    我是perl初学者。我经常发现自己在写作

    my $foo = $bar;
    $foo =~ s/regex/replacement/;
    doStuff($foo)
    

    我最想写的地方

    doStuff($bar->replace(s/regex/replacement/));
    

    或者类似的,而不是使用临时变量和三行。

    有办法吗?显然,当正则表达式足够复杂时,将其拆分以更好地解释是有意义的,但是当它只是 s/\s//g 用额外的变量把代码弄得乱七八糟是不对的。

    6 回复  |  直到 14 年前
        1
  •  7
  •   alexeypetrenko Amber    8 年前

    从Perl5.14开始,您可以使用 Non-destructive substitution

    使用 /r

    doStuff($bar=~s/regex/replacement/r);
    
        2
  •  14
  •   David W.    14 年前

    因为替换函数返回 1

    doStuff($foo =~ s/regex/replacement/);
    

    这个 doStuff 函数将使用 或者一个空字符串作为参数。替换函数没有理由不能返回结果字符串,而只是返回一个 如果成功的话。然而,这是Perl早期的设计决策。否则,这会发生什么?

    $foo = "widget";
    if ($foo =~ s/red/blue/) {
        print "We only sell blue stuff and not red stuff!\n";
    }
    

    生成的字符串仍然是 widget ,但替换实际上失败了。但是,如果替换返回的是结果字符串而不是空字符串,则 if

    $bar = "FOO!";
    if ($bar =~ s/FOO!//) {
       print "Fixed up \'\$bar\'!\n";
    }
    

    $bar 现在是空字符串。如果替换返回结果,它将返回一个空字符串。然而,换人实际上成功了,我想 如果 是真的。

    在大多数语言中,substitution函数返回结果字符串,您必须执行以下操作:

    if ($bar != replace("$bar", "/FOO!//")) {
       print "Fixed up \'\$bar''!\n";
    }
    

    因此,由于Perl的设计决策(基本上是为了更好地模拟 awk 语法),没有简单的方法来做你想做的事。但是你可以这样做:

    ($foo = $bar) =~ s/regex/replacement/;
    doStuff($foo);
    

    $foo $巴 $巴

        3
  •  5
  •   ysth    14 年前
    use Algorithm::Loops "Filter";
    
    # leaves $foo unchanged
    doStuff( Filter { s/this/that/ } $foo );
    
        4
  •  2
  •   Eugene Yarmash    14 年前

    你可以使用 do { }

    doStuff( do {(my $foo = $bar) =~ s/regex/replacement/; $foo} );
    
        5
  •  0
  •   Burkart Dimitre Novatchev    10 年前

    这就是你想要的吗

    my $foo = 'Replace this with that';
    (my $bar = $foo) =~ s/this/that/;
    print "Foo: $foo\nBar: $bar\n";
    

    印刷品:

    Foo: Replace this with that
    Bar: Replace that with that
    
        6
  •  -1
  •   David W.    14 年前

    sub replace (
        my $variable = shift;
        my $substring = shift;
    
        eval "\$variable =~ s${substring};";
        return $variable
    }
    
    doStuff(replace($foo, "/regex/replace/"));
    

    对于一个调用来说,这样做是不值得的,在这种情况下,它可能只会使您的代码更加混乱。但是,如果您已经做了十几次了,那么编写自己的函数来完成这项工作可能更有意义。