如何使用Ruby或Rails从URL中提取URL参数?


137

我有一些网址,例如

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

并且我想从这些网址中提取参数并将其放入哈希中。显然,我可以使用正则表达式,但是我只是想知道是否存在使用Ruby或Rails的更简单方法。我没有在Ruby模块中找到任何东西,URI但也许我错过了一些东西。

实际上,我需要一种可以做到这一点的方法:

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

您有什么建议吗?


1
Hash[*string.split('&').collect{|i|i.split('=')}.flatten] 这也可以,但是对于这种情况,这可能是最糟糕的选择。但是您仍然可能会发现此片段很有趣。(发表评论,因为我不认为这是一个答案:
Vojto 2010年

Answers:


162

我认为您想将任何给定的URL字符串转换为HASH?

您可以尝试http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html#M000075

require 'cgi'

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

退货

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

1
好,那是我想念的那个!与URI.parse使用时,它是完美的:CGI.parse(URI.parse(” example.com/...)返回所需的哈希感谢您的帮助。
Flackou

91
为了清楚起见,@ Flackou想要这样: CGI.parse(URI.parse(url).query)
格伦·杰克曼(Glenn jackman)2010年

我尚未对此进行测试,但是列出的第一个包含完整URL的键似乎确实是错误的。
李维

2
我实际上必须使用此功能: CGI::parse(URI::parse(url).query)
portforwardpodcast 2013年

151

我发现自己最近的项目也需要同样的东西。在Levi解决方案的基础上,这是一种更干净,更快捷的方法:

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

远远高于嘲讽机架要求更加轻便
加雷

2
好发现。如果您具有简单的参数(非嵌套)并且对性能敏感,则可能会感兴趣Rack :: Utils.parse_query。该代码值得阅读:github.com/rack/rack/blob/master/lib/rack/utils.rb
Levi

谢谢您,它非常有用:)
蓝色史密斯

这很好用,但不适用于具有相同名称的复选框:param1=value1&param1=value2。第二个值胜于第一个。
B 2015年

对于任何寻找反函数的人,它都是Rack::Utils.build_nested_query(params)(或用Rack::Utils.build_query(params)解析的Rack::Utils.parse_query)。
zelanix '16

99

刚刚通过上面的李维答案得到改善-

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

对于像上面的url这样的字符串,它将返回

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

7
好答案。很简单,就像op要求的那样处理完整的URL,结果值是字符串而不是数组,就像其他答案一样。谢谢。
jackocnr

3
正如我在上面评论的那样,对于任何想求逆的人来说,它都是Rack::Utils.build_query(params)
zelanix '16

1
当心-不完全相反,至少在Ruby 1.8.7 / Rails 2.3中不是。查询字符串foo [] = 1&foo [] = 2正确地解析为{“ foo” => [“ 1”,“ 2”]},但是build_query将其转换为“ foo = 1&foo = 2”,在解析时再次产生{“ foo” =>“ 2”}。
Raels '16

44

对于纯Ruby解决方案,请结合URI.parse使用CGI.parse(即使不需要Rails / Rack等也可以使用):

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

33

解决问题的方法不只一种。其他人向您展示了一些技巧。我知道另一个把戏。这是我的尝试:-

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

阅读的方法介绍::decode_www_form


13

查看可寻址的 gem-Ruby URI模块的流行替代品,它使查询解析变得容易:

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

(与URI不同,它显然也处理参数编码/解码)


-3

在Controller中,您应该可以访问名为的字典(哈希)params。因此,如果您知道每个查询参数的名称,则只需执行params[:param1]访问它即可。...如果您不知道参数的名称是什么,则可以遍历字典并获取键。

这里有一些简单的例子。


好的,我知道,它在带有请求的URL的控制器中可以很好地工作,但是如何对其他任意URL执行此操作?
Flackou 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.