正则表达式在Perl

问题描述:

GMF文件中ELSIF块处理:正则表达式在Perl

TSTARTCUSTEVSUMMROW_GPRS 
CUSTEVSUMMROW_GPRS GPRS - Subscriber Package (Paygo)|93452|MB|240|33952 
CUSTEVSUMMROW_GPRS GPRS - MBB Plan (Paygo)|93452|MB|160|20128 
TENDCUSTEVSUMMROW_GPRS 
TSTARTCUSTEVSUMMROW_GPRS_SIMPLE 
CUSTEVSUMMROW_GPRS_SIMPLE GPRS - LTE Roam Package|1529551|MB|85|260536 
CUSTEVSUMMROW_GPRS_SIMPLE GPRS - LTE Roam Package|65461|MB|20000|1309252 
TENDCUSTEVSUMMROW_GPRS_SIMPLE 

代码:

if ($line =~ m/^(CUSTEVSUMMROW_SIMPLE|CUSTEVSUMMROW_GPRS_SIMPLE|CUSTEVSUMMROW_GPRS|CUSTEVSUMMROW|CUSTPRODSUMMROW)\s(.*?)\|.*\|(.*?)$/) { 
    $tag  = $1; 
    $lineTxt = $2; 
    $amt  = $3; 
    if ($tag =~ m/^(CUSTEVSUMMROW|CUSTEVSUMMROW_SIMPLE)/) { 
     print "Processing some validations"; 
    } else { 
     Print " Mapping failed"; 
    } elsif ($tag =~ m/^(CUSTEVSUMMROW_GPRS|CUSTEVSUMMROW_GPRS_SIMPLE)/) { 
     if() { 
      #It has to do some validations. 
     } else {  
      #Failed; 
     } 
    } 
} 

当我尝试处理elseif条件无法处理。你能帮我解决这个问题吗?

输出:

Unable to map:CUSTEVSUMMROW_GPRS | GPRS - Data Only LTE Package Roaming | 34646.2272 
Unable to map:CUSTEVSUMMROW_GPRS | GPRS - LTE Dealer1 Package Roaming | 34609.3312 
Unable to map:CUSTEVSUMMROW_GPRS_SIMPLE | GPRS - Simple Subscriber Package 3 | 32.1899 
Unable to map:CUSTEVSUMMROW_GPRS_SIMPLE | GPRS - Simple Talk and Text Package | 0.2702 
+3

带'if()... else ... elsif()...'的代码永远不能执行elsif部分。它将执行前两个条款之一。 – AdrianHHH 2014-09-10 18:51:33

+1

您的输出与您的输入不符。在你的输出中,标签和标签之间有一个“|”。你的输入和代码说有一个空间。 – Schwern 2014-09-10 19:58:51

我会建议改变方法。而不是单独匹配线路的特定部分,并且不得不一遍又一遍地做,在开始时将其标记化。也就是说,将其分成语法片段。一旦解析结束,它将更容易处理。

以英语为例,解析诸如“去商店”,“你去商店”,“我去商店”,“我们去商店”,你可以搜索go|going|went在不同的位置,或者你可以分解成主题(去),动词(你),对象(存储),然后与他们合作。

它看起来像你有一个|分隔的字段集(你的文章在这个细节上发生冲突,根据需要进行调整)。在该管道上分割以标记。现在

my($tag, $description, $amount, $units, $limit, $something) = split m{\|}, $line; 

你可以$tag工作,而无需做进一步解析上整条生产线。

if($tag eq 'CUSTEVSUMMROW' or $tag eq 'CUSTEVSUMMROW_SIMPLE') { 
    ... 
} 
elsif($tag eq 'CUSTEVSUMMROW_GPRS' or 'CUSTEVSUMMROW_GPRS_SIMPLE') { 
    ... 
} 

可以使代码通过推动标签逻辑放到一个子程序简单。

sub is_tag_of_type { 
    my($tag, $type) = @_; 

    return 1 if $type eq 'GPRS' and $tag =~ /GPRS/; 
    return 1 if $type eq 'SIMPLE' and $tag =~ /SIMPLE/; 
    ... 
} 

或者,也许标签有自己的小语法,可以拆分为令牌。

sub tokenize_tag { 
    my $tag = shift; 

    my @tokens = split /_/, $tag; 
    return map { $ _ => 1 } @tokens; 
} 

然后你的代码来处理一条线看起来像这样。

my($tags, $description, $amount, $units, $limit, $something) = split m{\|}, $line; 
my %tags = tokenize_tags($tags); 

if($tags{GPRS}) { 
    ... 
} 
else { 
    ... 
} 

if ... else ... elsif是一个语法错误 - 你的代码将不能运行。假设elsif应该在ifelse之间,那么您还有一个问题:if条件中的正则表达式比elsif条件中的正则表达式更普遍。 CUSTEVSUMROW将匹配任何CUSTEVSUMMROW_GPRSCUSTEVSUMMROW_GPRS_SIMPLE会。交换ifelsif块,以便特定检查在通用之前进行。

if ($tag =~ /^CUSTEVSUMMROW_GPRS/) { 
    ... 
} 
elsif ($tag =~ /^CUSTEVSUMMROW/) { 
    ... 
} 
else { 
    ... 
} 
+0

或者用一个像文字边界('\ b')的锚点。 – Axeman 2014-09-10 22:28:39