【问题标题】:Is there an analogue of Ruby gsub method in Perl? [duplicate]Perl 中有 Ruby gsub 方法的类似物吗? [复制]
【发布时间】:2011-06-23 20:31:05
【问题描述】:

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

但确定有更好的方法吗?

【问题讨论】:

  • @ephemient => 链接的问题不包括使用替换作为子表达式
  • @Eric:当然可以。其中一个答案提到了 Perl 5.13.2 中的新 /r 选项(它将进入 Perl 5.14)。

标签: perl


【解决方案1】:

你用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】:

从您觉得在所有程序的顶部写 use 5.14.0 感觉舒服的那一天开始,您可以使用 s/// 运算符的 s/foo/bar/r 变体,它返回更改后的字符串,而不是原地修改原始字符串(在 perl 5.13.2 中添加)。

【讨论】:

  • 不幸的是,我们在 5.8.8 中停留在中世纪。大公司不喜欢前进。
  • 等等,什么?我以为它应该修改并返回?
  • @ysth 除非 delta 和 5.13 perlrequick 都在撒谎 :)
  • 一如既往:有效的 Perler effectiveperlprogramming.com/blog/659
【解决方案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!

【讨论】:

  • 它不会给我返回字符串,所以它不能在表达式中使用。
  • 如果在标量上下文中使用,则逗号后跟 var: ...,$foo 会这样做
猜你喜欢
  • 2012-09-05
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
  • 2011-08-28
  • 2012-02-10
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
相关资源
最近更新 更多