根据匹配的值替换regexp
单个REGEXP是否可以根据匹配的值执行不同的替换 例如,给定字符串“aaa-bbb-ccc-aaa-ddd”,我想将每次出现的“aaa”替换为“alpha”,“bbb”替换为“beta”,“ccc”替换为“gamma”,而“ddd”替换为“delta” 使用四个单独的regexp替换非常容易,我知道:根据匹配的值替换regexp,regex,perl,Regex,Perl,单个REGEXP是否可以根据匹配的值执行不同的替换 例如,给定字符串“aaa-bbb-ccc-aaa-ddd”,我想将每次出现的“aaa”替换为“alpha”,“bbb”替换为“beta”,“ccc”替换为“gamma”,而“ddd”替换为“delta” 使用四个单独的regexp替换非常容易,我知道: my $s = "aaa bbb ccc aaa ddd"; $s =~ s/aaa/alpha/g; $s =~ s/bbb/betaa/g; $s =~ s/ccc/gamma/g; $s
my $s = "aaa bbb ccc aaa ddd";
$s =~ s/aaa/alpha/g;
$s =~ s/bbb/betaa/g;
$s =~ s/ccc/gamma/g;
$s =~ s/ddd/delta/g;
问题是,仅仅用一句话就可以做到这一点,比如:
$s =~ s/$pattern/$replacement/g;
如果这很重要,我正在使用perl
这只是我试图解决的更复杂问题的一个简化示例;请不要开始争论我问错了问题,我应该用不同的方式来做。。。如果您真的这么认为,请忽略这个问题。您可以使用哈希值将匹配项替换为所需的值
my %replacement = (
"aaa" => "alpha",
"bbb" => "beta",
"ccc" => "gamma",
"ddd" => "delta",
);
my ($pattern) = map qr/$_/, join "|", map quotemeta, keys %replacement;
$s =~ s/($pattern)/$replacement{$1}/ge;
您可以使用哈希将匹配项替换为所需的值
my %replacement = (
"aaa" => "alpha",
"bbb" => "beta",
"ccc" => "gamma",
"ddd" => "delta",
);
my ($pattern) = map qr/$_/, join "|", map quotemeta, keys %replacement;
$s =~ s/($pattern)/$replacement{$1}/ge;
一个可以使用的东西是,这意味着右侧被解释为代码,匹配的文本被替换为该代码返回的值 例如,您可能需要以下内容:
$s =~ s/aaa|bbb|ccc/ $& eq 'aaa' ? 'alpha' : $& eq 'bbb' ? 'beta' : 'gamma' /eg;
或者更好(因为使用$&
会导致性能损失):
顺便说一下,如果表达式变得非常大,您可能还需要使用不同的分隔符和/x
修饰符来提高可读性。例如:
$s =~ s
{ ( aaa | bbb | ccc ) }
{
$1 eq 'aaa'
? 'alpha'
: $1 eq 'bbb'
? 'beta'
: 'gamma'
}egx;
编辑:质量 我提出这个答案是因为这个问题要求根据匹配值进行替换,但没有具体说明在他们的实际问题中(与他们展示的简化版本相反),匹配值的测试是否是简单的相等性测试 有人提出,基于
/e
的解决方案的质量不如基于散列的解决方案。在某种程度上,这一观察是有效的。在我看来,解决方案不同的两个质量因素是:
- 易读性:在这一点上,哈希解决方案无疑是赢家
- 资源利用率:在OP提出的示例中,
解决方案在时间和空间利用率方面都获胜。如果问题变得更大,这两种解决方案的规模将不同:/e
解决方案在时间上是线性的,在空间上是恒定的,而散列解决方案(大致)在时间上是恒定的,在空间上是线性的/e
/e
的速度提高了5–10%,而%的替换使用了588字节的内存。基准代码为:
my$str=‘aaa bbb ccc aaa ddd’;
我的$pattern=qr{(aaa | bbb | ccc | ddd)}x;
我的更换率=(“aaa”=>“α”、“bbb”=>“β”、“ccc”=>“γ”、“ddd”=>“δ”);
CMP这些(10000000,
{
e=>sub{my$s=$str;$s=~s/$pattern/$1eq'aaa'?'alpha':$1eq'bbb'?'beta':$1eq'c'?'gamma':'delta'/eg},
h=>sub{my$s=$str;$s=~s/$pattern/$replacement{$1}/ge;},
}
);
一个可以使用的东西是,这意味着右侧被解释为代码,匹配的文本被替换为该代码返回的值 例如,您可能需要以下内容:
$s =~ s/aaa|bbb|ccc/ $& eq 'aaa' ? 'alpha' : $& eq 'bbb' ? 'beta' : 'gamma' /eg;
或者更好(因为使用$&
会导致性能损失):
顺便说一下,如果表达式变得非常大,您可能还需要使用不同的分隔符和/x
修饰符来提高可读性。例如:
$s =~ s
{ ( aaa | bbb | ccc ) }
{
$1 eq 'aaa'
? 'alpha'
: $1 eq 'bbb'
? 'beta'
: 'gamma'
}egx;
编辑:质量 我提出这个答案是因为这个问题要求根据匹配值进行替换,但没有具体说明在他们的实际问题中(与他们展示的简化版本相反),匹配值的测试是否是简单的相等性测试 有人提出,基于
/e
的解决方案的质量不如基于散列的解决方案。在某种程度上,这一观察是有效的。在我看来,解决方案不同的两个质量因素是:
- 易读性:在这一点上,哈希解决方案无疑是赢家
- 资源利用率:在OP提出的示例中,
解决方案在时间和空间利用率方面都获胜。如果问题变得更大,这两种解决方案的规模将不同:/e
解决方案在时间上是线性的,在空间上是恒定的,而散列解决方案(大致)在时间上是恒定的,在空间上是线性的/e
/e
的速度提高了5–10%,而%的替换使用了588字节的内存。基准代码为:
my$str=‘aaa bbb ccc aaa ddd’;
我的$pattern=qr{(aaa | bbb | ccc | ddd)}x;
我的更换率=(“aaa”=>“α”、“bbb”=>“β”、“ccc”=>“γ”、“ddd”=>“δ”);
CMP这些(10000000,
{
e=>sub{my$s=$str;$s=~s/$pattern/$1eq'aaa'?'alpha':$1eq'bbb'?'beta':$1eq'c'?'gamma':'delta'/eg},
h=>sub{my$s=$str;$s=~s/$pattern/$replacement{$1}/ge;},
}
);
我不这么认为。但我可能错了,我不这么认为。但我可能错了,我不知道你的意思。在您的语句中,$pattern和$replacement是什么?您应该使用
my$pattern=join'|',映射quotemeta,对{length$b length$a}键进行排序%changes
以确保在aa
之前找到匹配项,例如,aabbcc
。我不知道您的意思。在您的语句中,$pattern和$replacement是什么?您应该使用my$pattern=join'|',映射quotemeta,排序{length$b length$a}键%changes
来确保匹配,例如,aabbcc
位于aa
之前。从任何角度看,哈希都比长字符串条件运算符好得多。从任何角度看,哈希都比长字符串条件运算符好得多。