Come estrarre i parametri URL da un URL con Ruby o Rails?


137

Ho alcuni URL, come

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

e vorrei estrarre i parametri da questi URL e inserirli in un hash. Ovviamente, potevo usare espressioni regolari, ma mi chiedevo solo se ci fossero modi più semplici per farlo con Ruby o Rails. Non ho trovato nulla nel modulo Ruby URIma forse mi sono perso qualcosa.

In effetti, ho bisogno di un metodo per farlo:

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

Avresti qualche consiglio?


1
Hash[*string.split('&').collect{|i|i.split('=')}.flatten] Funzionerebbe anche questo, ma è probabilmente l'opzione peggiore per questo caso. Ma potresti ancora trovare interessante questo frammento. (Pubblicando come commento poiché non considero questa una risposta :-))
Vojto

Risposte:


162

Penso che tu voglia trasformare una determinata stringa URL in un HASH?

Puoi provare http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html#M000075

require 'cgi'

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

ritorna

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

1
OK, quello era quello che mi mancava! È perfetto se utilizzato con URI.parse: CGI.parse (URI.parse (" esempio.com/… ) restituisce l'hash desiderato. Grazie per l'aiuto.
Flackou

91
Per chiarezza, @Flackou vuole questo: CGI.parse(URI.parse(url).query)
Glenn Jackman,

Non l'ho provato, ma la prima chiave elencata, contenente l'URL completo, sembra davvero sbagliata.
Levi,

2
In realtà ho dovuto usare questo: CGI::parse(URI::parse(url).query)
portforwardpodcast il

151

Mi sono ritrovato a aver bisogno della stessa cosa per un progetto recente. Basandosi sulla soluzione di Levi, ecco un metodo più pulito e veloce:

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

Molto più leggero che deridere una richiesta di Rack
Gareth

2
Buona scoperta. Se si dispone di parametri semplici (non nidificati) e sensibili alle prestazioni, Rack :: Utils.parse_query potrebbe essere interessante. Vale la pena leggere il codice: github.com/rack/rack/blob/master/lib/rack/utils.rb
Levi

Grazie, è molto utile :)
Blue Smith,

Questo metodo funziona bene, ma non funziona per caselle di controllo con lo stesso nome: param1=value1&param1=value2. Il secondo valore supera il primo.
B Seven

Per chiunque cerchi l'inverso, è Rack::Utils.build_nested_query(params)(o Rack::Utils.build_query(params)se analizzato con Rack::Utils.parse_query).
zelanix,

99

Appena migliorato con la risposta Levi sopra -

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

Per una stringa come sopra l'URL, tornerà

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

7
Bella risposta. semplice, elabora l'URL completo come richiesto dall'op e i valori dei risultati sono stringhe anziché matrici, come nelle altre risposte. Grazie.
Jackocnr,

3
Come ho commentato sopra, per chiunque cerchi l'inverso, lo è Rack::Utils.build_query(params).
zelanix,

1
Attenzione: non proprio il contrario, almeno non in Ruby 1.8.7 / Rails 2.3. Una stringa di query di foo [] = 1 & foo [] = 2 viene analizzata correttamente come {"foo" => ["1", "2"]}, ma build_query lo trasforma in "foo = 1 & foo = 2", che quando analizzato di nuovo produce {"foo" => "2"}.
Raels,

45

Per una soluzione Ruby pura combinare URI.parsecon CGI.parse(questo può essere utilizzato anche se non sono richiesti Rails / Rack ecc.):

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

33

Esistono più modi per risolvere il tuo problema. Altri ti hanno mostrato alcuni trucchi. Conosco un altro trucco. Ecco il mio tentativo: -

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"}

Leggi la descrizione del metodo di ::decode_www_form.


13

Dai un'occhiata alla gemma indirizzabile - un popolare sostituto del modulo URI di Ruby che semplifica l'analisi delle query:

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

(Apparentemente gestisce anche la codifica / decodifica dei parametri, a differenza dell'URI)


-3

Nel controller, dovresti essere in grado di accedere a un dizionario (hash) chiamato params. Quindi, se sai quali sono i nomi di ciascun parametro di query, allora falloparams[:param1] per accedervi ... Se non sai quali sono i nomi dei parametri, potresti attraversare il dizionario e ottenere le chiavi.

Alcuni semplici esempi qui .


OK, lo sapevo, funziona bene nel controller con l'URL richiesto, ma come farlo per altri URL arbitrari?
Flackou,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.