Perl:贪婪的自然拒绝工作

时间:2012-09-04 09:35:53

标签: perl

我正在尝试用另一个字符串替换字符串,但贪婪的性质似乎对我不起作用。下面是我的代码,其中“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

4 个答案:

答案 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调用(我假设函数名称都是大写的,在它们之间带' - ' - 否则调整)。第二部分将该行替换为您要显示的文本。

我还使用了xms选项,这些选项允许正则表达式中的注释等。您可以在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。

相关问题