2011-01-13 6 views
1

ブランチレスト演算子を使ってPerl v5.8.8とPerl v5.10.0との互換性のある正規表現を書くにはどうすればいいですか?perlのブランチリセット演算子5.8.8

私は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"; 
} 

どちらのバージョンにも互換性のある正規表現を作成する方法はありませんか?

おかげ

答えて

3

分岐リセットオペレータは、要件があるので、もし5.8 5.10(man perlreあたりなど)まで、あなたはそれなしで正規表現を記述する必要があります使用できません。

+0

oh!いいえ、教えてください。 私は別のマシンを持っていて、いくつかはv 5.8.8を持ち、いくつかは5.10.0を持っています。 コードを変更する必要がある場合は、すべてを変更する必要があります。 は、すべてのシステムをv5.10.0にアップグレードするのが良いオプションかもしれませんが、このバージョンは下位互換性がありますか?私はv5.8.8で書かれた他のperlコードがv5.10.0で動作するかどうかを意味しますか?互換性のある背景がありますか? – haris

+1

5.10にすべてをアップグレードするオプションがある場合は、そのことをお勧めします。 Perlの下位互換性は非常に良いので、あなたが何か本当に変わったことをしない限り、うまくいくはずです。多くのモジュール(DBIやDBD :: *ドライバのような)はネイティブコードに依存しているので、perlをアップグレードした後もそれらを再インストールする必要があります。 – arnsholt

+1

perl5-porterは、perlが後方互換性があることを保証するために非常に長くなります。あなたは最終的にあなたのコードで働くことを保証する責任があります。 – mfontani

3

(?|...)ブランチリセット演算子がPerl 5.10で追加されました。 regexを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; 

snpvと一致/不一致に重要serviceの特定の組み合わせはありますか?もしそうでなければ、(?|...)構成体を取り除くのは簡単です。

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 
}