Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex Perl同时替换多个字符串_Regex_Arrays_Perl_Replace_String Literals - Fatal编程技术网

Regex Perl同时替换多个字符串

Regex Perl同时替换多个字符串,regex,arrays,perl,replace,string-literals,Regex,Arrays,Perl,Replace,String Literals,有没有办法替换一个字符串中的多个字符串? 例如,我有字符串hello world what a lovely day,我想用其他东西替换what和lovely $sentence = "hello world what a lovely day"; @list = ("what", "lovely"); # strings to replace @replist = ("its", "bad"); # strings to replace with ($val = $sentence) =~ "

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

$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"..
你知道为什么它不起作用吗


谢谢。

首先,
tr
不是那样工作的;有关详细信息,请参阅
perldoc perlop
,但
tr
进行音译,与替换非常不同

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

# $val
$val =~ s/what/its/g;
$val =~ s/lovely/bad/g;
请注意,“同步”更改相当困难,但我们可以这样做,例如

%replacements = ("what" => "its", "lovely" => "bad");
($val = $sentence) =~ s/(@{[join "|", keys %replacements]})/$replacements{$1}/g;
(当然,用元字符替换字符串可能需要转义。)

这仍然只是在一个非常松散的术语意义上的同时,但在大多数情况下,它确实起到了一次替换的作用


另外,用
替换
“what”
比用
“its”
替换
“its”
“its”

更为正确,因为
tr///d
与您的请求无关(
tr/abc/12/d
用1替换a,用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;
要执行更像您在此处尝试的操作:

#! /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;
如果要进行大量此类替换,请先“编译”正则表达式:

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

...

$sentence =~ s/($matchkey)/$replace{$1}/g;
编辑:

要扩展我关于数组插值的评论,您可以更改
$”

实际上,这并不能改善这里的情况,但如果您已经在数组中拥有了密钥,则可能会:

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

这些词会永远是完整的词吗,还是有潜在的模式?
local $" = '|';
$sentence =~ s/(@keys)/$replace{$1}/g;