如何在保持原始字符串的同时对字符串执行Perl替换?

在Perl中,使用正则表达式对字符串执行替换并将值存储在不同的变量中而不改变原始值的好方法是什么?

我通常只是复制字符串到一个新变量,然后将其绑定到s///正则表达式,该正则表达式对新字符串进行替换,但我想知道是否有更好的方法来做到这一点?

$newstring = $oldstring;
$newstring =~ s/foo/bar/g;
227729 次浏览

这是我一直用来在不改变原始字符串的情况下获得修改后的字符串副本的习惯用法:

(my $newstring = $oldstring) =~ s/foo/bar/g;

在perl 5.14.0或更高版本中,你可以使用新的/r 非破坏性替代修饰剂:

my $newstring = $oldstring =~ s/foo/bar/gr;

< p > 注意:
上述解决方案在没有g的情况下也可以工作。它们也适用于任何其他修饰符。

< p > 参见:
perldoc perlrequick: Perl正则表达式快速入门 < / p >

声明:

(my $newstring = $oldstring) =~ s/foo/bar/g;

这相当于:

my $newstring = $oldstring;
$newstring =~ s/foo/bar/g;

或者,从Perl 5.13.2开始,你可以使用/r来做一个非破坏性的替换:

use 5.013;
#...
my $newstring = $oldstring =~ s/foo/bar/gr;

如果你用use strict;编写Perl,那么你会发现单行语法是无效的,即使声明了也是如此。

:

my ($newstring = $oldstring) =~ s/foo/bar/;

你会得到:

Can't declare scalar assignment in "my" at script.pl line 7, near ") =~"
Execution of script.pl aborted due to compilation errors.

相反,你一直在使用的语法,虽然多了一行,是用use strict;做它的语法正确的方式。对我来说,使用use strict;现在只是一种习惯。我是自动做的。每个人都应该。

#!/usr/bin/env perl -wT


use strict;


my $oldstring = "foo one foo two foo three";
my $newstring = $oldstring;
$newstring =~ s/foo/bar/g;


print "$oldstring","\n";
print "$newstring","\n";

use strict下,说:

(my $new = $original) =~ s/foo/bar/;

代替。

一行程序解决方案作为一种陈词滥调比好的代码更有用;好的Perl程序员会知道并理解它,但是它比您开始使用的两行复制-修改对联更不透明和可读。

换句话说,这样做的一个好方法是已经这样做。以可读性为代价的不必要的简洁并不是一种胜利。

我讨厌foo和bar ..到底是谁在编程中想出了这些非描述性的术语?

my $oldstring = "replace donotreplace replace donotreplace replace donotreplace";


my $newstring = $oldstring;
$newstring =~ s/replace/newword/g; # inplace replacement


print $newstring;
%: newword donotreplace newword donotreplace newword donotreplace

另一个5.14之前的解决方案:http://www.perlmonks.org/?node_id=346719(参见japhy的帖子)

由于他的方法使用map,它也适用于数组,但需要级联map来产生一个临时数组(否则原始数组将被修改):

my @orig = ('this', 'this sucks', 'what is this?');
my @list = map { s/this/that/; $_ } map { $_ } @orig;
# @orig unmodified

如果我只是在联机程序中使用这个,sprintf("%s", $oldstring)如何