可能重复:
How do I perform a Perl substitution on a string while keeping the original?
如何在不修改字符串本身的情况下在Perl中进行一行替换?我也希望它在表达式中可用,就像我在Ruby中可以做p s.gsub(/from/, 'to')
一样。
我能想到的只是
do {my $r = $s; $r =~ s/from/to/; $r}
但确定有更好的方法吗?
答案 0 :(得分:10)
从您在所有程序的顶部编写use 5.14.0
的日期开始,您可以使用s///
运算符的s/foo/bar/r变体,该运算符将返回已更改的字符串修改原件(在perl 5.13.2中添加)。
答案 1 :(得分:4)
您在do
找到的解决方案并不错,但您可以稍微缩短一下:
do {(my $r = $s) =~ s/from/to/; $r}
它仍然揭示了机制。您可以隐藏实现,也可以通过编写子例程将替换应用于列表。在大多数实现中,此函数称为apply
,您可以从List::Gen或List::MoreUtils或许多其他模块导入该函数。或者因为它太短,所以请自己写一下:
sub apply (&@) { # takes code block `&` and list `@`
my ($sub, @ret) = @_; # shallow copy of argument list
$sub->() for @ret; # apply code to each copy
wantarray ? @ret : pop @ret # list in list context, last elem in scalar
}
apply
创建参数列表的浅表副本,然后调用其代码块,该代码块应该修改$_
。不使用块的返回值。 apply
的行为类似于逗号,
运算符。在列表上下文中,它返回列表。在标量上下文中,它返回列表中的最后一项。
使用它:
my $new = apply {s/foo/bar/} $old;
my @new = apply {s/foo/bar/} qw( foot fool fooz );
答案 2 :(得分:3)
来自Perl's docs: Regexp-like operators:
($foo = $bar) =~ s/this/that/g; # copy first, then change
会匹配gsub
,而
$bar =~ s/this/that/g; # change
将匹配gsub!