2010-03-23 6 views
111

Ich habe einige URLs, wieWie URL-Parameter aus einer URL mit Ruby oder Rails extrahiert werden?

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

und ich möchte die Parameter aus dieser URLs extrahieren und sie in einem Hash zu bekommen. Natürlich konnte ich reguläre Ausdrücke verwenden, aber ich fragte mich nur, ob es leichtere Möglichkeiten gab, das mit Ruby oder Rails zu tun. Ich habe nichts im Ruby-Modul URI gefunden, aber vielleicht habe ich etwas verpasst.

In der Tat, ich brauche eine Methode, die das tun würde:

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

Möchten Sie einige Ratschläge haben?

+1

'Hash [* string.split ('&'). collect {| i | i.split ('='}}. flattern] ' Das würde auch funktionieren, aber es ist wahrscheinlich die schlechteste Option für diesen Fall.Aber vielleicht finden Sie dieses Snippet noch interessant. (Posting als Kommentar, da ich das nicht als Antwort ansehe :-)) – Vojto

Antwort

125

Ich denke, Sie möchten eine beliebige URL-Zeichenfolge in einen HASH verwandeln?

können Sie http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html#M000075 versuchen

require 'cgi' 

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

kehrt

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

OK, das war der, den ich vermisst habe! Es ist perfekt, wenn es mit URI.parse verwendet wird: CGI.parse (URI.parse ("http://www.example.com/something?param1=value1¶m2=value2¶m3=value3") .query) gibt den gewünschten Hash zurück. Danke für Ihre Hilfe. – Flackou

+77

Aus Gründen der Klarheit möchte @Flackou dies: 'CGI.parse (URI.parse (url) .query)' –

+0

Ich habe dies nicht getestet, aber der erste Schlüssel, der die vollständige URL enthält, scheint wirklich falsch. – Levi

-2

In Ihrem Controller sollten Sie auf ein Wörterbuch (Hash) namens params zugreifen können. Also, wenn Sie wissen, was die Namen der einzelnen Abfrageparameter sind, dann tun Sie einfach params[:param1], um darauf zuzugreifen ... Wenn Sie nicht wissen, was die Namen der Parameter sind, könnten Sie das Wörterbuch durchlaufen und die Schlüssel erhalten.

Einige einfache Beispiele here.

+0

OK, ich wusste das, es funktioniert gut im Controller mit der angeforderten URL, aber wie macht man das für andere beliebige URLs? – Flackou

129

fand ich mich für ein neues Projekt, die gleiche Sache zu benötigen. Aufbauend auf Levi-Lösung, hier ist eine saubere und schnelle Methode:

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

Viel leichter als eine Rack-Anfrage zu verspotten – Gareth

+2

Gut finden. Wenn Sie einfache Parameter (nicht verschachtelt) haben und leistungsabhängig sind, könnte Rack :: Utils.parse_query von Interesse sein. Der Code ist lesenswert: https://github.com/rack/rack/blob/master/lib/rack/utils.rb – Levi

+0

Das funktioniert hervorragend bei Rack-basierten Frameworks wie Ramaze! – desbest

81

Gerade Verbesserte mit Levi Antwort oben -

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

Für eine Zeichenfolge wie oben url, wird es zurückkehren

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

große Antwort. Einfach, verarbeitet die vollständige URL wie die Op-Abfragen, und die Ergebniswerte sind Zeichenfolgen anstelle von Arrays, wie in den anderen Antworten. Vielen Dank. – jackocnr

+1

Wie ich oben erwähnt habe, ist es für jeden, der nach der Umkehrung sucht, 'Rack :: Utils.build_query (params)'. – zelanix

+1

Vorsicht - nicht ganz das Gegenteil, zumindest nicht in Ruby 1.8.7/Rails 2.3. Eine Abfragezeichenfolge von foo [] = 1 & foo [] = 2 wird korrekt als {"foo" => ["1", "2"]} analysiert, aber build_query verwandelt das in "foo = 1 & foo = 2", was beim Parsen geschieht ergibt wiederum {"foo" => "2"}. – Raels

35

Für eine reine Rubinlösung kombinieren Sie URI.parse mit CGI.parse (dies kann auch verwendet werden, wenn Rails/Rack usw. nicht benötigt werden):

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

Es gibt mehr als eine Möglichkeit, Ihr Problem zu lösen. Andere haben dir die Tricks gezeigt. Ich kenne einen anderen Trick. Hier ist mein Versuch: -

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

die Methode docomentation von ::decode_www_form lesen.

10

Schauen Sie sich die addressable Juwel - ein beliebter Ersatz für Rubys URI-Modul, das leicht Abfrage Parsen macht:

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

(Es behandelt auch scheinbar param-Codierung/Decodierung, im Gegensatz zu URI)

+1

Humm. Das ist ein guter Edelstein. Ich mag es .. +1 –

Verwandte Themen