2011-07-15 10 views
5

ファイルの行を検索して、それらのファイルのいずれかが正規表現のセットのいずれかと一致するかどうかを調べたいとします。Perl正規表現のどの部分が文字列にマッチしているかを知るにはどうすればよいですか?

このような何か:

my @regs = (qr/a/, qr/b/, qr/c/); 
foreach my $line (<ARGV>) { 
    foreach my $reg (@regs) { 
     if ($line =~ /$reg/) { 
     printf("matched %s\n", $reg); 
     } 
    } 
} 

が、これは時間がかかることがあります。

正規表現のコンパイラが役に立ちそうです。このような最適化があります:

my $master_reg = join("|", @regs); # this is wrong syntax. what's the right way? 
foreach my $line (<ARGV>) { 
    $line =~ /$master_reg/; 
    my $matched = special_function(); 
    printf("matched the %sth reg: %s\n", $matched, $regs[$matched] 
} 

}「special_function」は正規表現の部分がマッチした私に言って特別なソースです

答えて

8

キャプチャカッコを使用してください。

my @matches = $foo =~ /(one)|(two)|(three)/; 
defined $matches[0] 
    and print "Matched 'one'\n"; 
defined $matches[1] 
    and print "Matched 'two'\n"; 
defined $matches[2] 
    and print "Matched 'three'\n"; 
5

追加キャプチャグループ:基本的な考え方は次のようになりますあなただけのようにも/(a|b|c)/を使用し、ちょうど$1を印刷している可能性が

"pear" =~ /(a)|(b)|(c)/; 
if (defined $1) { 
    print "Matched a\n"; 
} elsif (defined $2) { 
    print "Matched b\n"; 
} elsif (defined $3) { 
    print "Matched c\n"; 
} else { 
    print "No match\n"; 
} 

明らかにこの単純な例では、しかし、とき「A」、「B '、' c 'は任意に複雑な表現にすることができ、これが勝利です。

あなたがプログラムで正規表現を構築している場合は、各一致位置のオフセットを含んでいる、それは痛みを伴う番の変数を使用する必要が見つけ、その代わりに厳密を壊すのではなく、@-または@+配列に見えるかもしれません。 $-[0]は、パターンがまったく一致する限り常に設定されますが、$-[$n]は、キャプチャグループnが一致した場合にのみ定義された値を含みます。

関連する問題