Bagaimana cara mengekstrak parameter URL dari URL dengan Ruby atau Rails?


139

Saya memiliki beberapa URL, seperti

http://www.example.com/something?param1=value1&param2=value2&param3=value3

dan saya ingin mengekstrak parameter dari URL ini dan memasukkannya ke dalam Hash. Jelas, saya bisa menggunakan ekspresi reguler, tetapi saya hanya ingin tahu apakah ada cara yang lebih mudah untuk melakukannya dengan Ruby atau Rails. Saya belum menemukan apa pun di modul Ruby URItetapi mungkin saya melewatkan sesuatu.

Sebenarnya, saya membutuhkan metode yang akan melakukannya:

extract_parameters_from_url("http://www.example.com/something?param1=value1&param2=value2&param3=value3")
#=> {:param1 => 'value1', :param2 => 'value2', :param3 => 'value3'}

Apakah Anda punya nasihat?


1
Hash[*string.split('&').collect{|i|i.split('=')}.flatten] Ini akan berhasil juga, tapi mungkin itu pilihan terburuk untuk kasus ini. Tapi tetap saja Anda mungkin menganggap cuplikan ini menarik. (Posting sebagai komentar karena saya tidak menganggap ini sebagai jawaban :-))
Vojto

Jawaban:


163

Saya pikir Anda ingin mengubah string URL apa pun menjadi HASH?

Anda dapat mencoba http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html#M000075

require 'cgi'

CGI::parse('param1=value1&param2=value2&param3=value3')

kembali

{"param1"=>["value1"], "param2"=>["value2"], "param3"=>["value3"]}

2
Oke, itu yang saya lewatkan! Sempurna jika digunakan dengan URI.parse: CGI.parse (URI.parse (" example.com/… ) mengembalikan Hash yang diinginkan. Terima kasih atas bantuan Anda.
Flackou

92
Untuk kejelasan, @Flackou menginginkan ini: CGI.parse(URI.parse(url).query)
glenn jackman

Saya belum menguji ini, tetapi kunci pertama yang terdaftar, yang berisi url lengkap, tampaknya sangat salah.
Levi

2
Saya sebenarnya harus menggunakan ini: CGI::parse(URI::parse(url).query)
portforwardpodcast

152

Saya menemukan diri saya membutuhkan hal yang sama untuk proyek baru-baru ini. Berdasarkan solusi Levi's, inilah metode yang lebih bersih dan lebih cepat:

Rack::Utils.parse_nested_query 'param1=value1&param2=value2&param3=value3'
# => {"param1"=>"value1", "param2"=>"value2", "param3"=>"value3"}

Jauh lebih ringan daripada mengejek permintaan Rack
Gareth

2
Temuan bagus. Jika Anda memiliki parameter sederhana (tidak bersarang) dan peka terhadap kinerja, Rack :: Utils.parse_query mungkin menarik. Kode ini layak dibaca: github.com/rack/rack/blob/master/lib/rack/utils.rb
Levi

Terima kasih, ini sangat berguna :)
Blue Smith

Ini bekerja dengan baik tetapi tidak bekerja untuk kotak centang dengan nama yang sama: param1=value1&param1=value2. Nilai kedua mengalahkan nilai pertama.
B Tujuh

Bagi siapa saja yang mencari kebalikannya, itu Rack::Utils.build_nested_query(params) (atau Rack::Utils.build_query(params)jika diurai dengan Rack::Utils.parse_query).
zelanix

101

Baru saja ditingkatkan dengan jawaban Levi di atas -

Rack::Utils.parse_query URI("http://example.com?par=hello&par2=bye").query

Untuk string seperti url di atas, itu akan kembali

{ "par" => "hello", "par2" => "bye" } 

7
jawaban yang bagus. sederhana, memproses URL lengkap seperti yang diminta op, dan nilai hasilnya adalah string, bukan array, seperti di jawaban lain. Terima kasih.
jackocnr

3
Seperti yang saya komentari di atas, bagi siapa pun yang mencari kebalikannya, itu Rack::Utils.build_query(params).
zelanix

1
Hati-hati - tidak sebaliknya, setidaknya di Ruby 1.8.7 / Rails 2.3. String kueri foo [] = 1 & foo [] = 2 diurai dengan benar sebagai {"foo" => ["1", "2"]}, tetapi build_query mengubahnya menjadi "foo = 1 & foo = 2", yang ketika diurai sekali lagi menghasilkan {"foo" => "2"}.
Raels

48

Untuk solusi Ruby murni menggabungkan URI.parsedengan CGI.parse(ini dapat digunakan bahkan jika Rails / Rack dll tidak diperlukan):

CGI.parse(URI.parse(url).query) 
# =>  {"name1" => ["value1"], "name2" => ["value1", "value2", ...] }

36

Ada lebih dari satu cara, untuk menyelesaikan masalah Anda. Orang lain telah menunjukkan beberapa trik. Saya tahu trik lain. Inilah percobaan saya: -

require 'uri'
url = "http://www.example.com/something?param1=value1&param2=value2&param3=value3"
uri = URI(url)
# => #<URI::HTTP:0x89e4898 URL:http://www.example.com/something?param1=value1&param2=value2&param3=value3>
URI::decode_www_form(uri.query).to_h # if you are in 2.1 or later version of Ruby
# => {"param1"=>"value1", "param2"=>"value2", "param3"=>"value3"}
Hash[URI::decode_www_form(uri.query)] # if you are below 2.1 version of Ruby
# => {"param1"=>"value1", "param2"=>"value2", "param3"=>"value3"}

Bacalah dokumentasi metode ::decode_www_form.


13

Lihat permata yang dapat dialamatkan - pengganti populer untuk modul URI Ruby yang membuat penguraian kueri menjadi mudah:

require "addressable/uri"
uri = Addressable::URI.parse("http://www.example.com/something?param1=value1&param2=value2&param3=value3")
uri.query_values['param1']
=> 'value1'

(Ini juga tampaknya menangani encoding / decoding param, tidak seperti URI)


-3

Di Controller Anda, Anda seharusnya bisa mengakses kamus (hash) yang dipanggil params. Jadi, jika Anda tahu nama setiap parameter kueri, lakukan sajaparams[:param1] untuk mengaksesnya ... Jika Anda tidak tahu apa nama parameternya, Anda dapat menelusuri kamus dan mendapatkan kuncinya.

Beberapa contoh sederhana di sini .


Oke, saya tahu itu, ini berfungsi dengan baik di pengontrol dengan URL yang diminta, tetapi bagaimana melakukannya untuk URL sembarang orang lain?
Flackou
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.