2011-01-17 17 views
1

私はキーのためのregexと値のためのblockとハッシュを持っています。以下のような何か:Rubyで正規表現キャプチャをブロックに渡す方法はありますか?

{ 'test (.+?)' => { puts $1 } } 

ない正確ような、明らかに、ブロックはPROCとして格納されているが、それはアイデアだから。

私はその上で、後に正規表現マッチを持っているが、多くこの

hash.each do |pattern, action| 
    if /#{pattern}/i.match(string) 
     action.call 
    end 
end 

のような考えは、私は将来的には時に拡大することが少し簡単にするために、ハッシュに離れてブロックを保存することだったに見えます、今ではregexキャプチャはブロックに渡されません。 regex(いくつかのregexパターンには1つのキャプチャがあり、他のものには3つがあるかもしれない)のキャプチャをサポートする方法がありますか?

+0

これはあなたの質問には対処しませんが、パターンを正規表現の代わりに文字列として保存する理由は何ですか? – cam

+0

本当の理由はありません。私はハッシュを格納するメソッドを使用しているので、読みやすく( 'on(pattern、&block)ハッシュ[パターン] =ブロックは基本的に私が使っている方法です)、' on 'テストを書くのが簡単だったようです(。+?) 'do do $ 1 end'を実行します。 –

答えて

3

あなたのprocsにマッチデータを渡すとどうなりますか?

hash.each do |pattern, action| 
    if pattern.match(string) 
    action.call($~) 
    end 
end 

あなたのハッシュはなる:

{ /test (.+?)/i => lambda { |matchdata| puts matchdata[1] } } 
+0

ありがとうございます。私は 'first'の代わりに' matchdata [1] 'を使わなければなりませんでしたが、それはうまくいきます。 –

+0

ああ、私はまずそれをテストすべきだった。私は将来私の答えを変えました。 – cam

1

私はブロックを1つずつにそれらを渡し、ハッシュ要素を歩くHash.findを使用します。

hash = {/foo/ => lambda { 'foo' }, /bar/ => lambda { 'bar' } } 
str = 'foo' 
puts hash.find{ |n,v| str =~ n }.to_a.last.call 

もちろん、私はlambdaを使用していますが、それは十分に近いです。このような

何か:true勝利を返します1。また、一致がない場合は、ゼロ値を処理する必要があります。私の場合、私はto_a.last.callをチェーンしていましたが、実際のところは反応したくないでしょう。そうしないとRubyが怒ってしまいます。

多くのパターンを検索したり、多くのテキストを処理している場合は、そのたびに正規表現を再コンパイルしなければ検索が遅くなります。私はそれを避けるために正規表現オブジェクトとしてキーを格納することをお勧めします。