我正在尝试用另一个字符串替换字符串,但贪婪的性质似乎对我不起作用。下面是我的代码,其中“PERFORM GET-APLCY”被识别并正确替换,但字符串“PERFORM GET-APLCY-SOI-CVG-WVR”以及许多其他此类字符串正被“PERFORM GET-APLCY”的替换字符串替换”
s/PERFORM $func[$i]\.*/# PERFORM $func[$i]\.\n $hash{$func[$i]}/g;
在字符串匹配和替换期间,句号是可选的。我也尝试将模式匹配为$ func [$ i] \ b 请帮我理解问题所在。
提前致谢, Faez
答案 0 :(得分:1)
如果点是可选的,为什么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
答案 1 :(得分:1)
您似乎在循环函数名称,并为每个名称调用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;
答案 2 :(得分:0)
我猜$ func [$ i]包含“GET-APLCY”。如果是这样,这是因为星号仅适用于点,实际点,而不是“任何字符”。尝试
s/PERFORM $func[$i].*/# PERFORM $func[$i]\.\n $hash{$func[$i]}/g;
答案 3 :(得分:0)
我很确定你试图为$ i做一些循环。在这种情况下最有可能 GET-APLCY位于GET-APLCY-SOI-CVG-WVR之前的@func阵列中。所以我建议在进入循环之前反向排序@func。