perl 5.8.8中的分支重置操作符

时间:2011-01-13 10:40:19

标签: perl version

我想知道如何使用分支rest操作符编写与Perl v5.8.8和Perl v5.10.0兼容的正则表达式?

我已经在其中编写了一个带有regexp的perl代码,并且代码在Perl v5.10.0中工作正常,但是当我在另一台机器上使用perl v5.8.8执行相同的代码时,它会出现以下错误;

Sequence (?|...) not recognized in regex; marked by <-- HERE in ...

这是代码;

#!/usr/bin/perl -w

my $i = "[1284336000] NEW SERVICE STATE: snpv3;service1;HIGH;SAFE;1;warnings";

if($i =~ /^\[\d+\]\sNEW\sSERVICE\sSTATE:\s(?|(snpv1);(service1)|(snpv1);(service2)|(snpv2);(service2)|(snpv3);(service1)|(snpv3);(service3)|(snpv4);(service4)|(snpv5);(service4)|(snpv6);(service6)|(snpv7);(service7));(HIGH);(\w+);(\d).+$/){
    print "matched\n";
}
else{
    print "not matched\n";
}

有人可以建议如何制作与任一版本兼容的正则表达式。

谢谢

2 个答案:

答案 0 :(得分:3)

分支重置运算符在Perl 5.10(按man perlre)之前不可用,因此如果要求5.8,则必须在没有它的情况下编写正则表达式。

答案 1 :(得分:3)

在Perl 5.10中添加了(?|...)分支重置运算符。如果你想让你的正则表达式向后兼容早期版本的Perl,你需要修改它以删除构造。

这是您当前的模式,使用/x修饰符编写易读性:

my $pattern = qr/
    ^
    \[\d+\]
    \s
    NEW\sSERVICE\sSTATE:
    \s
    (?|
          (snpv1);(service1)
        | (snpv1);(service2)
        | (snpv2);(service2)
        | (snpv3);(service1)
        | (snpv3);(service3)
        | (snpv4);(service4)
        | (snpv5);(service4)
        | (snpv6);(service6)
        | (snpv7);(service7)
    )
    ;
    (HIGH);
    (\w+);
    (\d)
    .+
    $
/x;

snpvservice的特定组合对匹配/不匹配很重要吗?如果没有,很容易摆脱(?|...)构造。

my $pattern = qr/
    ^
    \[\d+\]
    \s
    NEW\sSERVICE\sSTATE:
    \s
    (snpv\d);
    (service\d);
    (HIGH);
    (\w+);
    (\d)
    .+
    $
/x;

如果组合很重要,您仍然可以使用此模式,但您需要进行后续检查。

my %valid = (
    snpv1 => { service1 => 1, service2 => 1 },
    snpv2 => { service2 => 1 },
    snpv3 => { service1 => 1, service3 => 1 },
    snpv4 => { service4 => 1 },
    snpv5 => { service4 => 1 },
    snpv6 => { service6 => 1 },
    snpv7 => { service7 => 1 },
);

if ($i =~ $pattern && $valid{$1}{$2}) {
    # match
}
else {
    # no match
}