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

Regex 如何在保留原始字符串的同时对字符串执行Perl替换?,regex,perl,replace,Regex,Perl,Replace,在Perl中,使用正则表达式对字符串执行替换并将值存储在不同的变量中而不更改原始值的好方法是什么 我通常只是将字符串复制到一个新变量,然后将其绑定到对新字符串进行替换的s//regex,但我想知道是否有更好的方法来实现这一点 $newstring = $oldstring; $newstring =~ s/foo/bar/g; 这是我一直用来在不改变原始字符串的情况下获得字符串的修改副本的习惯用法: (my $newstring = $oldstring) =~ s/foo/bar/g; 在

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

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

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

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

(my $newstring = $oldstring) =~ s/foo/bar/g;
在perl 5.14.0或更高版本中,可以使用新的
/r


注意:
上述解决方案在没有
g
的情况下也能工作。它们还可以与任何其他修改器一起使用

另请参见:
声明:

(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;

如果使用
编写Perl,请使用strict,则您会发现单行语法无效,即使在声明时也是如此

与:

你会得到:

Can't declare scalar assignment in "my" at script.pl line 7, near ") =~"
Execution of script.pl aborted due to compilation errors.
相反,您一直使用的语法(虽然行较长),是使用
use strict。对我来说,使用
使用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";

下使用strict
,说:

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

相反。

单行程序解决方案作为一个shibboleth比好代码更有用;好的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之前的解决方案:(见japhy的帖子)

由于他的方法使用
map
,因此它也适用于数组,但需要级联
map
来生成临时数组(否则会修改原始数组):


如果我只是在oneliner中使用它,那么,
sprintf(“%s”,$oldstring)

无论是否在严格使用中。变量的最小范围++我想知道是不是像
my$new=$\ufor$old=~s/foo/bar
行吗?@Benoit,我相信你的意思是
s/foo/bar/对于我的$newstring=$oldstring它可以工作,但它要奇怪得多。啊,但是单行版本在无意中修改错误字符串的问题上不会出现错误。单行版本如果执行正确,就不会出现错误。但这是一个单独的问题。您可能认为这是不必要的简洁,但必须键入两次变量名才能使用一次,这是失败点数的两倍。它对熟悉该语言的人来说是完全可读的,甚至在我们的Perl学习课程中也是如此
而不是
-w
,您可以获得更大的控制权:例如,如果您想暂时关闭代码块中的警告。您是否忘记了顶部正则表达式中的
g
?这与原来的有什么不同?(而且我认为你想要的是一个错误。该代码的实际输出是
newword donotnewword newword donotnewword newword donotnewword
请参阅。。。如果JoGotta使用了传统的和熟悉的
foo
bar
,他的答案应该是准确的。再一次证明,习俗的存在是有原因的,只有通过艰苦的方式才能学到教训谁维基百科有。包括:“foobar的词源可以从二战时期的军事俚语FUBAR中派生出来,后来bowdlerised改为foobar。foo一词本身在更早的时候就被使用了……已知的第一次在编程环境中使用印刷术语出现在1965年版的麻省理工学院技术工程新闻中。”
(my $new = $original) =~ s/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
my @orig = ('this', 'this sucks', 'what is this?');
my @list = map { s/this/that/; $_ } map { $_ } @orig;
# @orig unmodified