2011-02-09 58 views
2

可能重複:
How do I perform a Perl substitution on a string while keeping the original?在Perl中是否有類似Ruby的gsub方法?

我怎樣做一個管線的更換在Perl,而無需修改字符串本身?我也希望它能夠在表達式中使用,就像我在Ruby中可以使用p s.gsub(/from/, 'to')一樣。

所有我能想到的是

do {my $r = $s; $r =~ s/from/to/; $r} 

,但肯定有一個更好的辦法?

+0

@ephemient =>鏈接的問題不包括使用替代作爲子表達 – 2011-02-09 02:21:02

+2

@Eric:當然可以。其中一個答案在Perl 5.13.2中提到了新的`/ r`選項(它將使其成爲Perl 5.14)。 – ephemient 2011-02-09 04:25:56

回答

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); 
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!

+0

它不會給我回串,所以它不能在表達式中使用。 – vava 2011-02-09 01:46:36

+0

如果在標量上下文中使用,則逗號後跟var:`...,$ foo`將會這樣做 – 2011-02-09 01:51:19

10

開始的一天,你在所有的程序的頂部手感舒適寫作use 5.14.0,您可以使用s/foo/bar/r變體s///操作的,它返回改變的字符串,而不是修改原來的位置(添加在perl 5.13.2中)。

相關問題