web-dev-qa-db-ja.com

Ruby変数名を使用した正規表現

Ruby変数名の値に基づく正規表現パターンを作成/使用することはできますか?

たとえば、Ruby文字列を使用して次のことができることを知っています。

str = "my string"
str2 = "This is #{str}" # => "This is my string"

正規表現でも同じことをしたい:

var = "Value"
str = "a test Value"
str.gsub( /#{var}/, 'foo' ) # => "a test foo"

明らかにそれはリストされているようには機能しませんが、私がやりたいことを示すための例としてそれを置いています。変数のコンテンツの値に基づいて正規表現一致する必要があります。

95
cpjolicoeur

あなたが動作しないと思うコードは、動作します:

var = "Value"
str = "a test Value"
p str.gsub( /#{var}/, 'foo' )   # => "a test foo"

Varに正規表現のメタ文字を含めることができる場合、物事はより興味深いものになります。それがあり、それらのmatacharactersが正規表現で通常行うことをしたい場合、同じgsubが動作します:

var = "Value|a|test"
str = "a test Value"
str.gsub( /#{var}/, 'foo' ) # => "foo foo foo"

ただし、検索文字列にメタキャラクターが含まれていて、notメタキャラクターとして解釈する場合は、Regexp.escapeを次のように使用します。

var = "*This*"
str = "*This* is a string"
p str.gsub( /#{Regexp.escape(var)}/, 'foo' )
# => "foo is a string"

または、gsubに正規表現ではなく文字列を指定します。 1.8.7以上のMRIでは、gsubは文字列置換引数を正規表現ではなくプレーンストリングとして扱います。

var = "*This*"
str = "*This* is a string"
p str.gsub(var, 'foo' ) # => "foo is a string"

(以前は、gsubの文字列置換引数が自動的に正規表現に変換されていました。1.6でそのようになったことを知っています。どのバージョンが変更を導入したかは思い出せません)。

他の回答で述べたように、補間の代替としてRegexp.newを使用できます。

var = "*This*"
str = "*This* is a string"
p str.gsub(Regexp.new(Regexp.escape(var)), 'foo' )
# => "foo is a string"
170
Wayne Conrad

動作しますが、gsub!を使用するか、戻り値を別の変数に割り当てる必要があります

var = "Value"
str = "a test Value"
str.gsub!( /#{var}/, 'foo' )  # Or this: new_str = str.gsub( /#{var}/, 'foo' )
puts str
13
FMc

はい


str.gsub Regexp.new(var), 'foo'
9
DigitalRoss

Rubyの変数を介して正規表現を使用できます。

var = /Value/
str = "a test Value"
str.gsub( /#{var}/, 'foo' )
4
GeekTantra
str.gsub( Regex.new("#{var}"), 'foo' )
3
DNNX