2017-09-09 18 views
1

私は動的に構築されている正規表現をしました:名前付きキャプチャグループは、動的な正規表現では動作しません

permitted_keys = %w[attachment avatar banner document] 

# my actual key 
key = 'banner_content_type' 

# g1 will be the captured grouped or nil 
/(?<g1>#{permitted_keys.join('|')})_content_type/ =~ key 

p "g1 #{g1.inspect}" 

問題動的にこの正規表現を構築し、私は次のようなエラーになってるということです:

/(?<g1>attachment|avatar|banner|document)_content_type/ =~ key 

それは完全に動作します:私はこのように、静的正規表現に値を入れただし

NameError (undefined local variable or method `g1' for...

、。

最初のアプローチの問題点は何ですか? TIA。

PS:

私はすでにターミナルで次比較しました:

/(?<g1>#{permitted_keys.join('|')})_content_type/ == 
/(?<g1>attachment|avatar|banner|document)_content_type/ 

を...そして、それはtrueを返します。

あなたは以下のリンクの例を確認することができます。

Example 1
Example 2

答えて

2

最初のアプローチの問題は、正規表現リテラルの文字列補間を使用すると、ローカル変数の割り当てを無効にしていることです。 Regexp#=~から:

If =~ is used with a regexp literal with named captures, captured strings (or nil) is assigned to local variables named by the capture names.

... snipped...

This assignment is implemented in the Ruby parser. The parser detects ‘regexp-literal =~ expression’ for the assignment. The regexp must be a literal without interpolation and placed at left hand side.

... snipped ...

A regexp interpolation, #{} , also disables the assignment.

自動的にこの(正直私は=~がそうだろう知らなかった)のようなローカル変数を割り当てるには、必ずだけキャプチャを取得するためにRegexp#matchを使用することができますが、私はとにかくのかわかりません

match_data = /(?<g1>#{permitted_keys.join('|')})_content_type/.match(key) 
match_data['g1'] 
# => "banner" 

か、グローバルに対処好きなら:

/(?<g1>#{permitted_keys.join('|')})_content_type/ =~ key 
$~['g1'] 
# => "banner" 
+0

おかげで非常に有用な答えのために:) –

関連する問題