0

我正在尝试用另一个字符串替换一个字符串,但贪婪的本性似乎对我不起作用。下面是我的代码,其中“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 请帮助我了解问题可能是什么。

在此先感谢, 法埃兹

4

4 回答 4

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
于 2012-09-04T09:45:09.613 回答
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调用(我假设函数名称都是大写的,它们之间带有“-” - 否则进行调整)。第二部分用您要显示的文本替换该行。

我还使用了xms选项,它允许在正则表达式中添加注释等。您可以在 下找到有关这些的更多信息perldoc perlop

-line的普通版本s应该是:

s/PERFORM ([A-Z-]+)\.?/"#  PERFORM $1.\n" . $hash{$1}/eg;
于 2012-09-04T12:33:24.410 回答
0

我很确定你试图为 $i 做某种循环。在这种情况下,很可能 GET-APLCY 位于 GET-APLCY-SOI-CVG-WVR 之前的 @func 数组中。所以我建议在进入循环之前对 @func 进行反向排序。

于 2012-09-04T21:20:09.320 回答
0

我猜这 $func[$i] 包含“GET-APLCY”。如果是这样,这是因为星号仅适用于点,一个实际的点,而不是“任何字符”。尝试

s/PERFORM $func[$i].*/#  PERFORM $func[$i]\.\n $hash{$func[$i]}/g;
于 2012-09-04T09:50:55.180 回答