Ekspresi reguler Ruby menggunakan nama variabel

105

Apakah mungkin untuk membuat / menggunakan pola ekspresi reguler di ruby ​​yang didasarkan pada nilai nama variabel?

Misalnya, kita semua tahu bahwa kita dapat melakukan hal berikut dengan string Ruby:

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

Saya ingin melakukan hal yang sama dengan ekspresi reguler:

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

Jelas itu tidak berfungsi seperti yang tercantum, saya hanya meletakkannya di sana sebagai contoh untuk menunjukkan apa yang ingin saya lakukan. Saya perlu mencocokkan ekspresi reguler berdasarkan nilai konten variabel.

cpjolicoeur.dll
sumber

Jawaban:

184

Kode yang menurut Anda tidak berfungsi, berfungsi:

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

Hal-hal menjadi lebih menarik jika var dapat berisi meta-karakter ekspresi reguler. Jika ya dan Anda ingin karakter matakarakter tersebut melakukan apa yang biasanya mereka lakukan dalam ekspresi reguler, maka gsub yang sama akan berfungsi:

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

Namun, jika string pencarian Anda berisi karakter meta dan Anda tidak ingin ditafsirkan sebagai karakter meta, gunakan Regexp.escape seperti ini:

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

Atau berikan saja gsub string sebagai ganti ekspresi reguler. Dalam MRI> = 1.8.7, gsub akan memperlakukan argumen penggantian string sebagai string biasa, bukan ekspresi reguler:

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

(Dulu argumen penggantian string ke gsub secara otomatis diubah menjadi ekspresi reguler. Saya tahu itu seperti itu di 1.6. Saya tidak ingat versi mana yang memperkenalkan perubahan).

Seperti disebutkan dalam jawaban lain, Anda dapat menggunakan Regexp.new sebagai alternatif interpolasi:

var = "*This*"
str = "*This* is a string"
p str.gsub(Regexp.new(Regexp.escape(var)), 'foo' )
# => "foo is a string"
Wayne Conrad
sumber
4
Petunjuk tentang Regexp.escape adalah apa yang saya tidak tahu saya butuhkan. Terima kasih!
Jeff Paquette
regxPlayerVariable = '(. *?) =. *? document \ .getElementById (# {pluginPlayeVariable})' di sini saya menerapkan semua di atas tetapi ini tidak berfungsi.
SSP
1
@SSP Mungkin ada baiknya untuk menjelaskan masalah dalam pertanyaan terpisah.
Wayne Conrad
13

Ini berfungsi, tetapi Anda perlu menggunakan gsub!atau menetapkan pengembalian ke variabel lain

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

Iya


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

Anda dapat menggunakan ekspresi reguler melalui variabel di ruby:

var = /Value/
str = "a test Value"
str.gsub( /#{var}/, 'foo' )
GeekTantra
sumber
1
Saya tidak yakin mengapa ini hanya memiliki suara negatif. Saya mencobanya dan berhasil, meskipun Anda tidak memerlukan garis miring regex di varparameter pertama variabel dan gsub.
Tyler Collier
Menurut saya, titik garis miring di gsub adalah untuk menunjukkan bahwa regex dapat berisi variabel yang juga merupakan regex. Variabel tidak harus tipe string (dan kenyataannya, regex lebih baik untuk alasan yang diuraikan dalam jawaban Wayne).
mahemoff