150

我有一些网址,比如

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

我想从这些 URL 中提取参数并将它们放在哈希中。显然,我可以使用正则表达式,但我只是想知道使用 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'}

你有什么建议吗?

4

10 回答 10

180

我认为您想将任何给定的 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"]}
于 2010-03-23T14:20:11.783 回答
169

我发现自己在最近的一个项目中需要同样的东西。在 Levi's 解决方案的基础上,这是一种更清洁、更快速的方法:

Rack::Utils.parse_nested_query 'param1=value1&param2=value2&param3=value3'
# => {"param1"=>"value1", "param2"=>"value2", "param3"=>"value3"}
于 2010-07-10T05:46:47.330 回答
108

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" } 
于 2012-02-22T15:56:05.047 回答
50

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

CGI.parse(URI.parse(url).query) 
# =>  {"name1" => ["value1"], "name2" => ["value1", "value2", ...] }
于 2012-06-07T10:25:01.437 回答
41

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

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

于 2014-09-01T02:48:52.423 回答
16

查看addressable 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 不同,它显然也处理参数编码/解码)

于 2015-01-02T15:59:06.217 回答
2

在 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"} 
于 2021-10-22T17:45:55.093 回答
2

你也可以使用这个方法


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


它安全且容易得多

于 2021-05-28T20:46:59.507 回答
1

遗憾的是,当尝试从有问题的 URL 中提取查询参数时, theURI和库都会中断。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": "john@email.com"}
于 2021-08-24T10:51:31.450 回答
-4

在您的控制器中,您应该能够访问一个名为params. 因此,如果您知道每个查询参数的名称是什么,那么只需params[:param1]访问它......如果您不知道参数的名称是什么,您可以遍历字典并获取键。

这里有一些简单的例子。

于 2010-03-23T14:07:56.083 回答