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

Cha*_*les 10 regex perl substitution

有没有办法用正则表达式内联替换文本,而不是从变量中取出文本并将其存储在变量中?

我是初学者.我经常发现自己写作

my $foo = $bar;
$foo =~ s/regex/replacement/;
doStuff($foo)
Run Code Online (Sandbox Code Playgroud)

我真的很想写的地方

doStuff($bar->replace(s/regex/replacement/));
Run Code Online (Sandbox Code Playgroud)

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

有没有办法做到这一点?显然,当正则表达式足够复杂时,将它拆分出来以便更好地解释是有意义的,但是当它只是s/\s//g用其他变量使代码混乱时感觉是错误的.

Dav*_* W. 14

你真的不能做你想要的,因为替换函数返回一个1if if working或者一个空字符串,如果它不起作用.这意味着如果你这样做:

doStuff($foo =~ s/regex/replacement/);
Run Code Online (Sandbox Code Playgroud)

doStuff函数将使用任一1或空字符串作为参数.没有理由为什么替换函数不能返回结果字符串而不是只返回1它是否有效.然而,这是Perl早期的设计决定.否则,这会发生什么?

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

结果字符串仍然存在widget,但替换实际上失败了.但是,如果替换返回结果字符串而不是空字符串,则if仍然为真.

然后,考虑这种情况:

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

$bar现在是一个空字符串.如果替换返回结果,则返回空字符串.然而,替换实际上成功了,我希望我if是真的.

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

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

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

($foo = $bar) =~ s/regex/replacement/;
doStuff($foo);
Run Code Online (Sandbox Code Playgroud)

这将在$foo没有首先为其赋值的情况下进行到位设置$bar.$bar会保持不变.

  • 从技术上讲,`s ///`返回所做的替换次数(如果为0则返回空字符串).但如果你不使用`/ g`,显然不能超过1. (2认同)
  • 从理论上讲,你可以为`s ///`设置一个修饰符来告诉它制作字符串的副本,(可能)修改副本,并返回新的字符串.我想我之前已经看到了这个建议,但它还没有(还)进入Perl,它可能永远不会被添加. (2认同)

yst*_*sth 5

use Algorithm::Loops "Filter";

# leaves $foo unchanged
doStuff( Filter { s/this/that/ } $foo );
Run Code Online (Sandbox Code Playgroud)


ale*_*nko 5

从perl 5.14开始,您可以使用非破坏性替换来实现所需的行为.

使用/r修饰符可以这样做:

doStuff($bar=~s/regex/replacement/r);
Run Code Online (Sandbox Code Playgroud)