Interpolasi string ke dalam regex


160

Saya perlu mengganti nilai string ke dalam ekspresi reguler saya di Ruby. Apakah ada cara mudah untuk melakukan ini? Sebagai contoh:

foo = "0.0.0.0"
goo = "here is some other stuff 0.0.0.0" 
if goo =~ /value of foo here dynamically/
  puts "success!"
end

Apakah Anda mencoba untuk melihat apakah foo adalah substring dari goo? Saya pikir tidak jelas apa yang Anda minta.
Neall

Jika demikian, goo.include? (Foo) sudah cukup!
glenn mcdonald

1
Tidak, saya tidak mencoba melihat apakah foo adalah substring dari goo; Saya juga perlu melakukan beberapa penangkapan, karena itu termasuk tidak bekerja.
Chris Bunch

Jawaban:



125

Perhatikan bahwa Regexp.quotedalam jawaban Jon L. ini penting!

if goo =~ /#{Regexp.quote(foo)}/

Jika Anda hanya melakukan versi "jelas":

if goo =~ /#{foo}/

maka periode dalam teks pertandingan Anda diperlakukan sebagai wildcard regexp, dan "0.0.0.0"akan cocok "0a0b0c0".

Perhatikan juga bahwa jika Anda benar-benar hanya ingin memeriksa kecocokan substring, Anda bisa melakukannya

if goo.include?(foo)

yang tidak memerlukan kutipan tambahan atau mengkhawatirkan karakter khusus.


3
Perhatikan bahwa kebalikannya (tidak menggunakan .quote()) juga bisa berguna jika Anda ingin membuat regex menggunakan string.
Jesse

"jika Anda benar-benar hanya ingin memeriksa kecocokan substring, Anda dapat melakukan if goo.include?(foo)" => Benar ketika Anda tertarik untuk memeriksa keberadaan. Jika Anda tertarik untuk mengganti dan sudah menggunakan String.gsub, maka Regexp.quote mungkin satu-satunya pilihan Anda.
Isaac Betesh

Hanya untuk menambahkan ke Jesse jika itu tidak jelas, ini berarti hanya melewati serangkaian karakter yang tidak perlu Anda hindari Regexp.newatau Regexp.compile.
dylankb

Terima kasih atas penjelasan yang bermanfaat tentang mengapa kami mungkin ingin menggunakan Regexp.quote
Wylliam Judd

7

Mungkin Regexp.escape(foo)akan menjadi titik awal, tetapi ada alasan yang baik Anda tidak dapat menggunakan ekspresi-interpolasi lebih konvensional: "my stuff #{mysubstitutionvariable}"?

Anda juga bisa menggunakan !goo.match(foo).nil?string literal.



3

Gunakan Regexp.new baru:

if goo =~ Regexp.new(foo) # Evaluates to /0.0.0.0/

3

Inilah jawaban lain yang terbatas tetapi bermanfaat:

Saya menemukan saya bahwa saya dapat dengan mudah memasukkan ke dalam regex tanpa menggunakan Regexp.quote atau Regexp.escape jika saya hanya menggunakan tanda kutip tunggal pada string input saya: (cocok dengan alamat IP)

IP_REGEX = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'

my_str = "192.0.89.234 blahblah text 1.2, 1.4" # get the first ssh key 
# replace the ip, for demonstration
my_str.gsub!(/#{IP_REGEX}/,"192.0.2.0") 
puts my_str # "192.0.2.0 blahblah text 1.2, 1.4"

kutipan tunggal hanya menafsirkan \\ dan \ '.

http://en.wikibooks.org/wiki/Ruby_Programming/Strings#Single_quotes

Ini membantu saya ketika saya perlu menggunakan bagian panjang yang sama dari regex beberapa kali. Tidak universal, tapi cocok dengan contoh pertanyaan, saya percaya.


Saya ingin tahu apa yang akan dipikirkan posting saya di sini, tetapi saya ragu itu akan terlihat sejauh ini di sini sekarang.
Plasmarob

-2
foo = "0.0.0.0"
goo = "here is some other stuff 0.0.0.0" 

puts "success!" if goo =~ /#{foo}/

2
Tidak, ini akan memberikan kesalahan "true" untuk "di sini ada beberapa hal lain 070x0! 0", karena titik-titik tersebut adalah wildcard regexp.
glenn mcdonald
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.