2012-01-18 12 views
0

キャプチャがPerl正規表現マッチングで定義されているかどうかをテストするにはどうすればよいですか?キャプチャがPerl正規表現マッチングで定義されているかどうかをテストするには?

#!/usr/bin/env perl 
use v5.10; 
my $str="foobar 
barfoo"; 

while($str =~ m/(?:(f.*))|(?:(b.*))/g) { 
    say "+ $1"; 
    say "- $2"; 
} 

これは、出力

​​

私がしたいことはありながら

+ foobar 
- barfoo 

すなわち、 $1または$2が一致しない場合は、印刷しないでください。

+0

「$ 1」、「$ 2」などは後方参照ではありません。 "後方参照"は '\ 1'、' \ 2'などを指します。これは前に取り込まれた文字列と一致する正規表現パターンです。 – ikegami

答えて

3

定義済みのものはテストしていないので、+/-いずれの方法でも印刷されます。

while($str =~ m/(?:(f.*))|(?:(b.*))/g) { 
    say "+ $1" if defined($1); 
    say "- $2" if defined($2); 
} 
2

defined(...)機能を使用してください。 $1が定義されていない場合、defined($1)はfalseを返します。

1

それは$1や友人を設定する副作用に頼らないのがベストです。あなたが実証したように、それはバグの家族の原因であり、避けられるべきです。代わりに、単にマッチ演算子の戻り値を使用します。

while(my ($plus, $minus) = $str =~ m/(?:(f.*))|(?:(b.*))/g) { 
    say "+ $plus"; 
    say "- $minus"; 
+0

+1、私には聞こえるように聞こえる。特に失敗した試合では$ 2などが前回の試合の結果を参照する可能性があるためです。 TIMTOWTDIを仮定すると、マッチが一致するかどうかを検出するためには、別の、うまくいっても明示的な方法が必要ですが、見つけられないようです。 –

+0

どの部分をより明示的にしたいですか?一致操作の戻り値がfalseの場合、一致しませんでした。私は 'if(SOMEMATCH){'または 'while(SOMEMATCH){'と書いて、いつも失敗事例を防ぐ。ビルトインとサードパーティの両方のPerlで何百もの他の関数が同様に動作します(つまり、失敗時にfalse値を返す)。 – daxim

+0

構文です。もちろん、関数の戻り値を使用するのはルーチンです。しかし、SOMEMATCHは中置式であり、割り当てのようにも見えます(ええ、そうではありませんが、それは私を悩ませます)。そのような表現の価値を使うのは避ける傾向があります。なぜなら、私はそれを読み、見直すことが難しいと考えるからです。 "より明示的"とは、Regexp :: Commonが提供する($ this)というような '$ matches = $ regex-> match($ input)'のようなものを意味します。 –

関連する問題