Perl同时替换多个字符串

Tra*_*v92 12 regex arrays perl replace string-literals

有没有办法替换字符串中的多个字符串?例如,我有字符串hello world what a lovely day,我想替换whatlovely其他东西..

$sentence = "hello world what a lovely day";
@list = ("what", "lovely"); # strings to replace
@replist = ("its", "bad"); # strings to replace with
($val = $sentence) =~ "tr/@list/@replist/d";
print "$val\n"; # should print "hello world its a bad day"..
Run Code Online (Sandbox Code Playgroud)

任何想法为什么它不起作用?

谢谢.

muh*_*ten 13

首先,tr不这样做; 咨询perldoc perlop细节,但是tr音译,并且与替换非常不同.

为此,更正确的替换方法是

# $val
$val =~ s/what/its/g;
$val =~ s/lovely/bad/g;
Run Code Online (Sandbox Code Playgroud)

请注意,"同时"更改相当困难,但我们可以这样做,例如,

%replacements = ("what" => "its", "lovely" => "bad");
($val = $sentence) =~ s/(@{[join "|", keys %replacements]})/$replacements{$1}/g;
Run Code Online (Sandbox Code Playgroud)

(当然,可能需要转义以使用元字符替换字符串.)

这仍然只是在一个非常松散的意义上同时发生,但是对于大多数目的而言,它确实表现为好像一次性完成替换.

此外,它是更正确的替换"what""it's",而不是"its".


Jul*_*ren 6

好吧,主要是因为它tr///d与你的请求没有关系(tr/abc/12/d用1代替b,用2替换b,并删除c).此外,默认情况下,数组不会以对您的任务有用的方式插入到正则表达式中.此外,如果没有散列查找或子程序调用或其他逻辑,您无法在操作的右侧做出决策s///.

要回答标题中的问题,您可以同时执行多次替换 - 呃,方便连续 - 以这种方式:

#! /usr/bin/env perl
use common::sense;

my $sentence = "hello world what a lovely day";

for ($sentence) {
  s/what/it's/;
  s/lovely/bad/
}

say $sentence;
Run Code Online (Sandbox Code Playgroud)

要做更像你在这里尝试的事情:

#! /usr/bin/env perl
use common::sense;

my $sentence = "hello world what a lovely day";

my %replace = (
  what => "it's",
  lovely => 'bad'
);

$sentence =~ s/(@{[join '|', map { quotemeta($_) } keys %replace]})/$replace{$1}/g;

say $sentence;
Run Code Online (Sandbox Code Playgroud)

如果你要做很多这样的替换,首先'编译'正则表达式:

my $matchkey = qr/@{[join '|', map { quotemeta($_) } keys %replace]}/;

...

$sentence =~ s/($matchkey)/$replace{$1}/g;
Run Code Online (Sandbox Code Playgroud)

编辑:

为了扩展我对阵列插值的评论,你可以改变$":

local $" = '|';
$sentence =~ s/(@{[keys %replace]})/$replace{$1}/g;
# --> $sentence =~ s/(what|lovely)/$replace{$1}/g;
Run Code Online (Sandbox Code Playgroud)

这里没有改进的东西,真的,虽然你可能已经拥有了数组中的键:

local $" = '|';
$sentence =~ s/(@keys)/$replace{$1}/g;
Run Code Online (Sandbox Code Playgroud)