How to extract URL parameters from a URL with Ruby or Rails?

130,142

Solution 1

I think you want to turn any given URL string into a HASH?

You can try http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html#M000075

require 'cgi'

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

returns

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

Solution 2

I found myself needing the same thing for a recent project. Building on Levi's solution, here's a cleaner and faster method:

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

Solution 3

Just Improved with Levi answer above -

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

For a string like above url, it will return

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

Solution 4

For a pure Ruby solution combine URI.parse with CGI.parse (this can be used even if Rails/Rack etc. are not required):

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

Solution 5

There more than one ways, to solve your problem. Others has shown you the some tricks. I know another trick. Here is my try :-

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

Read the method docomentation of ::decode_www_form.

Share:
130,142

Related videos on Youtube

Flackou
Author by

Flackou

Updated on October 23, 2021

Comments

  • Flackou
    Flackou over 2 years

    I have some URLs, like

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

    and I would like to extract the parameters from these URLs and get them in a Hash. Obviously, I could use regular expressions, but I was just wondering if there was easier ways to do that with Ruby or Rails. I haven't found anything in the Ruby module URI but perhaps I missed something.

    In fact, I need a method that would do that:

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

    Would you have some advices?

    • Vojto
      Vojto almost 14 years
      Hash[*string.split('&').collect{|i|i.split('=')}.flatten] This would work too, but it's probably the worst option for this case. But still you might find this snippet interesting. (Posting as comment since I don't consider this an answer :-))
  • Flackou
    Flackou about 14 years
    OK, I knew that, it works well in the controller with the requested URL, but how to do that for others arbitrary URLs?
  • Flackou
    Flackou about 14 years
    OK, that was the one I missed! It's perfect when used with URI.parse : CGI.parse(URI.parse("example.com/…) returns the desired Hash. Thanks for your help.
  • glenn jackman
    glenn jackman about 14 years
    For clarity, @Flackou wants this: CGI.parse(URI.parse(url).query)
  • Levi
    Levi about 14 years
    I haven't tested this, but the first key listed, containing the full url, seems really wrong.
  • Gareth
    Gareth almost 13 years
    Much more lightweight than mocking a Rack request
  • Levi
    Levi over 12 years
    Good find. If you have simple params (non-nested) and are performance sensitive, Rack::Utils.parse_query might be of interest. The code is worth reading: github.com/rack/rack/blob/master/lib/rack/utils.rb
  • benathon
    benathon about 11 years
    I actually had to use this: CGI::parse(URI::parse(url).query)
  • jackocnr
    jackocnr over 10 years
    great answer. simple, processes the full URL like the op asks, and the result values are strings instead of arrays, like in the other answers. thanks.
  • Blue Smith
    Blue Smith almost 10 years
    Thank you, it's very useful :)
  • B Seven
    B Seven over 8 years
    This works well but does not work for checkboxes with the same name: param1=value1&param1=value2. The second value trumps the first.
  • zelanix
    zelanix about 8 years
    For anyone looking for the inverse, it's Rack::Utils.build_nested_query(params) (or Rack::Utils.build_query(params) if parsed with Rack::Utils.parse_query).
  • zelanix
    zelanix about 8 years
    As I commented above, for anyone looking for the inverse, it's Rack::Utils.build_query(params).
  • Raels
    Raels almost 8 years
    Beware - not quite the inverse, at least not in Ruby 1.8.7 / Rails 2.3. A query string of foo[]=1&foo[]=2 is correctly parsed as { "foo" =>["1","2"] }, but build_query turns that into "foo=1&foo=2", which when parsed again yields { "foo"=>"2"}.
  • Yossi Shasho
    Yossi Shasho about 7 years
    This method crashes sometimes because of encoding issues. I found the CGI:parse method to be more stable (see answer above)
  • wbharding
    wbharding about 3 years
    Took me a minute to realize that due to lack of wrapping params, this answer isn't readily extended. Rack::Utils.parse_query(URI("http://example.com?par=hello&pa‌​r2=bye").query) yields a hash that can be further modified.
  • Kelsey Hannan
    Kelsey Hannan over 2 years
    Sadly it looks this gem, like the URI library, has difficulty parsing query parameters in situations where the URL is weird. I.e. both fail to find query parameters when urls are odd, e.g. this: http://localhost:4300/webapp/foo/#//controller/action? Leaving me to use a hack like: Rack::Utils.parse_nested_query(url.split("?").last) to get the query parameters for parsing.
  • Michael Brawn
    Michael Brawn about 2 years
    Look, no additional libraries needed 👍
  • Jason L.
    Jason L. about 2 years
    This is elegant.