在Perl中是否有类似的Ruby gsub方法?

时间:2011-02-09 01:38:02

标签: perl perl5

  

可能重复:
  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}

但确定有更好的方法吗?

3 个答案:

答案 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::GenList::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!