我有一些网址,比如
http://www.example.com/something?param1=value1¶m2=value2¶m3=value3
我想从这些 URL 中提取参数并将它们放入哈希中。显然,我可以使用正则表达式,但我只是想知道是否有更简单的方法可以使用 Ruby 或 Rails 来做到这一点。我在 Ruby 模块中没有找到任何东西
URI
但也许我错过了一些东西。
事实上,我需要一个可以做到这一点的方法:
extract_parameters_from_url("http://www.example.com/something?param1=value1¶m2=value2¶m3=value3")
#=> {:param1 => 'value1', :param2 => 'value2', :param3 => 'value3'}
您有什么建议吗?
我想你想将任何给定的 URL 字符串转换为 HASH?
你可以尝试http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html#M000075
require 'cgi'
CGI::parse('param1=value1¶m2=value2¶m3=value3')
退货
{"param1"=>["value1"], "param2"=>["value2"], "param3"=>["value3"]}
我发现自己在最近的项目中需要同样的东西。 基于 Levi's 解决方案,这里有一个更干净、更快速的方法:
Rack::Utils.parse_nested_query 'param1=value1¶m2=value2¶m3=value3'
# => {"param1"=>"value1", "param2"=>"value2", "param3"=>"value3"}
刚刚根据上面的李维答案进行了改进 -
Rack::Utils.parse_query URI("http://example.com?par=hello&par2=bye").query
对于像上面 url 这样的字符串,它将返回
{ "par" => "hello", "par2" => "bye" }
对于纯 Ruby 解决方案,请将
URI.parse
与 CGI.parse
结合起来(即使不需要 Rails/Rack 等,也可以使用):
CGI.parse(URI.parse(url).query)
# => {"name1" => ["value1"], "name2" => ["value1", "value2", ...] }
解决您的问题的方法不止一种。其他人已经向您展示了一些技巧。我还知道另一个窍门。这是我的尝试:-
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"}
::decode_www_form
的方法文档。
查看 addressable gem - Ruby URI 模块的流行替代品,使查询解析变得容易:
require "addressable/uri"
uri = Addressable::URI.parse("http://www.example.com/something?param1=value1¶m2=value2¶m3=value3")
uri.query_values['param1']
=> 'value1'
(它显然还处理参数编码/解码,与 URI 不同)
对于 Ruby 2.7/3,使用 CGI 可能是一种过时的方法。
这里有一个使用 URI 实现此目的的巧妙方法:
uri = URI.parse 'https://duckduckgo.com/?q=ruby+programming+language'
params = Hash[URI.decode_www_form uri.query]
# => {"q"=>"ruby programming language"}
你也可以用这个方法
require 'uri'
require 'cgi'
uri = URI("https://example.com/?query=1&q=2&query=5")
a = CGI::parse(uri.query)
puts a #=> {"query"=>["1", "5"], "q"=>["2"]}
puts a["query"].to_s #=> ["1", "5"]
puts a["query"][0] #=> 1
puts a["query"][1] #=> 5
puts a["q"][0] #=> 2
它安全且更容易
遗憾的是,当尝试从有问题的 URL 中提取查询参数时,
URI
和 addressable
库都会崩溃。例如。这会破坏两者:
http://localhost:4300/webapp/foo/#//controller/action?account=001-001-111&email=john%40email.com
基于 Arthur / Levi 的解决方案,使用
url.split("?").try(:last)
,您可以仅获取 URL 的查询参数部分,并使用 Rack::Utils.parse_nested_query
将该参数字符串解析为哈希值。
或完整:
Rack::Utils.parse_nested_query(url.split("?").try(:last))
回到我的例子:
{"account": "001-001-111", "email": "[email protected]"}
上面的答案写得很好,并且达到了目的,但是我尝试了一些查询操作并想在这里分享。所以,这是我的看法:
URI("http://example.com?par=hello&par2=bye").query.split('&').map { |param| {query_param: param.split('=')[0] , value: param.split('=')[1]} }
它达到了目的并为每个查询参数返回一个对象数组。话虽如此,请记住ROR的COC原则。
在您的控制器中,您应该能够访问名为
params
的字典(哈希)。因此,如果您知道每个查询参数的名称是什么,那么只需执行 params[:param1]
即可访问它...如果您不知道参数的名称是什么,您可以遍历字典并获取键。
一些简单的例子这里。