¿Cómo extraer parámetros de URL de una URL con Ruby o Rails?


137

Tengo algunas URL, como

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

y me gustaría extraer los parámetros de estas URL y ponerlos en un hash. Obviamente, podría usar expresiones regulares, pero me preguntaba si había formas más fáciles de hacerlo con Ruby o Rails. No he encontrado nada en el módulo Ruby, URIpero tal vez me perdí algo.

De hecho, necesito un método que haga eso:

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

¿Te darías algunos consejos?


1
Hash[*string.split('&').collect{|i|i.split('=')}.flatten] Esto también funcionaría, pero probablemente sea la peor opción para este caso. Pero aún así puede encontrar este fragmento interesante. (Publicando como comentario ya que no considero que esto sea una respuesta :-))
Vojto

Respuestas:


162

¿Creo que quieres convertir cualquier cadena URL en un HASH?

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

require 'cgi'

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

devoluciones

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

1
OK, ese fue el que me perdí! Es perfecto cuando se usa con URI.parse: CGI.parse (URI.parse (" example.com/… ) devuelve el hash deseado. Gracias por su ayuda.
Flackou

9191
Para mayor claridad, @Flackou quiere esto: CGI.parse(URI.parse(url).query)
Glenn Jackman

No he probado esto, pero la primera clave enumerada, que contiene la URL completa, parece realmente incorrecta.
Levi

2
De hecho, tuve que usar esto: CGI::parse(URI::parse(url).query)
portforwardpodcast

151

Me encontré necesitando lo mismo para un proyecto reciente. Basándose en la solución de Levi, aquí hay un método más limpio y rápido:

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

Mucho más ligero que burlarse de una solicitud de rack
Gareth

2
Buen descubrimiento. Si tiene parámetros simples (no anidados) y es sensible al rendimiento, Rack :: Utils.parse_query podría ser de interés. Vale la pena leer el código: github.com/rack/rack/blob/master/lib/rack/utils.rb
Levi

Gracias, es muy útil :)
Blue Smith

Esto funciona bien pero no funciona para casillas de verificación con el mismo nombre: param1=value1&param1=value2. El segundo valor triunfa sobre el primero.
B Seven

Para cualquiera que busque el inverso, es Rack::Utils.build_nested_query(params)(o Rack::Utils.build_query(params)si se analiza Rack::Utils.parse_query).
zelanix

99

Solo mejorado con la respuesta de Levi arriba:

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

Para una cadena como la URL anterior, devolverá

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

77
gran respuesta. simple, procesa la URL completa como las preguntas de operación, y los valores del resultado son cadenas en lugar de matrices, como en las otras respuestas. Gracias.
jackocnr

3
Como comenté anteriormente, para cualquiera que busque lo contrario, es Rack::Utils.build_query(params).
zelanix

1
Cuidado: no todo lo contrario, al menos no en Ruby 1.8.7 / Rails 2.3. Una cadena de consulta de foo [] = 1 & foo [] = 2 se analiza correctamente como {"foo" => ["1", "2"]}, pero build_query lo convierte en "foo = 1 & foo = 2", que cuando se analiza nuevamente produce {"foo" => "2"}.
Raels

44

Para una solución Ruby pura, combínela URI.parsecon CGI.parse(esto puede usarse incluso si no se requieren Rails / Rack, etc.):

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

33

Hay más de una forma de resolver su problema. Otros te han mostrado algunos trucos. Conozco otro truco. Aquí está mi intento: -

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

Lea el método docomentation de ::decode_www_form.


13

Eche un vistazo a la gema direccionable , un reemplazo popular para el módulo URI de Ruby que facilita el análisis de consultas:

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

(Al parecer, también maneja la codificación / decodificación de parámetros, a diferencia de URI)


-3

En su controlador, debería poder acceder a un diccionario (hash) llamado params. Por lo tanto, si sabe cuáles son los nombres de cada parámetro de consulta, simplemente params[:param1]acceda a él ... Si no sabe cuáles son los nombres de los parámetros, puede recorrer el diccionario y obtener las claves.

Algunos ejemplos simples aquí .


OK, lo sabía, funciona bien en el controlador con la URL solicitada, pero ¿cómo hacer eso para otras URL arbitrarias?
Flackou
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.