How to extract URL parameters from a URL with Ruby or Rails?
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¶m2=value2¶m3=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¶m2=value2¶m3=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¶m2=value2¶m3=value3"
uri = URI(url)
# => #<URI::HTTP:0x89e4898 URL:http://www.example.com/something?param1=value1¶m2=value2¶m3=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
.
Related videos on Youtube
Flackou
Updated on October 23, 2021Comments
-
Flackou over 2 years
I have some URLs, like
http://www.example.com/something?param1=value1¶m2=value2¶m3=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¶m2=value2¶m3=value3") #=> {:param1 => 'value1', :param2 => 'value2', :param3 => 'value3'}
Would you have some advices?
-
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 about 14 yearsOK, I knew that, it works well in the controller with the requested URL, but how to do that for others arbitrary URLs?
-
Flackou about 14 yearsOK, 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 about 14 yearsFor clarity, @Flackou wants this:
CGI.parse(URI.parse(url).query)
-
Levi about 14 yearsI haven't tested this, but the first key listed, containing the full url, seems really wrong.
-
Gareth almost 13 yearsMuch more lightweight than mocking a Rack request
-
Levi over 12 yearsGood 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 about 11 yearsI actually had to use this:
CGI::parse(URI::parse(url).query)
-
jackocnr over 10 yearsgreat 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 almost 10 yearsThank you, it's very useful :)
-
B Seven over 8 yearsThis works well but does not work for checkboxes with the same name:
param1=value1¶m1=value2
. The second value trumps the first. -
zelanix about 8 yearsFor anyone looking for the inverse, it's
Rack::Utils.build_nested_query(params)
(orRack::Utils.build_query(params)
if parsed withRack::Utils.parse_query
). -
zelanix about 8 yearsAs I commented above, for anyone looking for the inverse, it's
Rack::Utils.build_query(params)
. -
Raels almost 8 yearsBeware - 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 about 7 yearsThis method crashes sometimes because of encoding issues. I found the
CGI:parse
method to be more stable (see answer above) -
wbharding about 3 yearsTook 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&par2=bye").query)
yields a hash that can be further modified. -
Kelsey Hannan over 2 yearsSadly 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 whenurl
s 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 about 2 yearsLook, no additional libraries needed 👍
-
Jason L. about 2 yearsThis is elegant.