我正试图用另一个字符串替换一个字符串,但贪婪的本质似乎对我不起作用。下面是我的代码,其中"PERFORM GET-APLCY"被正确识别和替换,但字符串"PERFORMGET-APCCY-SOI-VG-WVR"和许多其他这样的字符串正在被"PERFORMGet-APLCY"的替换字符串替换。
s/PERFORM $func[$i].*/# PERFORM $func[$i].n $hash{$func[$i]}/g;
其中,在字符串匹配和替换期间,句号是可选的。我还尝试将要匹配的模式设置为$func[$I]\b请帮助我了解问题可能是什么。
提前感谢,Faez
如果点是可选的,为什么GET-APLCY-
不应该与GET-APLCY.
匹配?
简单的解决方案:按长度降序对数组进行排序。
@func = sort { length $b <=> length $a } @func
测试脚本:
#!/usr/bin/perl
use warnings;
use strict;
use feature 'say';
my %hash = ('GET-APLCY' => 'REP1',
'GET-APLCY-SOI-CVG-WVR' => 'REP2',
'GET-APLCY-SOI-MNG-CVRW' => 'REP3',
);
my @func = sort { length $b <=> length $a } keys %hash;
while (<DATA>) {
chomp;
print;
print "t -> t";
for my $i (0 .. $#func) {
s/$func[$i]/$hash{$func[$i]}/;
}
say;
}
__DATA__
GET-APLCY param
GET-APLCY- param
GET-APLCY. param
GET-APLCY-SOI. param
GET-APLCY-SOI-CVG-WVR param
GET-APLCY-SOI-MNG-CVRW param
您似乎在函数名上循环,并为每个函数名调用s///
。另一种选择是使用e
选项,并一次性完成所有操作(无需循环):
my %hash = (
'GET-APLCY' => 'replacement 1',
'GET-APLCY-SOI-CVG-WVR' => 'replacement 2',
);
s{
PERFORM s+ # 'PERFORM' keyword
([A-Z-]+) # the original function name
.? # an optional period
}{
"# PERFORM $1.n" . $hash{$1};
}xmsge;
e
使得替换部分被评估为表达式。基本上,第一部分查找所有PERFORM
调用(我假设函数名都是大写,中间有'-',否则进行调整)。第二部分用要显示的文本替换该行。
我还使用了x
、m
和s
选项,这些选项允许在正则表达式中添加注释。你可以在perldoc perlop
下找到更多关于这些的信息。
s
行的普通版本应该是:
s/PERFORM ([A-Z-]+).?/"# PERFORM $1.n" . $hash{$1}/eg;
我猜$func[$I]包含"GET-APLCY"。如果是这样,这是因为星形只适用于点,一个实际的点,而不是"任何字符"。尝试
s/PERFORM $func[$i].*/# PERFORM $func[$i].n $hash{$func[$i]}/g;
我敢肯定你正在为$I做某种循环。在这种情况下,很可能GET-APPLY位于GET-APPLY-SOI-CVG-WVR之前的@func阵列中。所以我建议在进入循环之前对@func进行反向排序。