我想从URL中取出一个参数,但不知道它是哪个参数,然后重新组装URL。Ruby中从URL中删除参数的最优雅方式是什么?
我想这并不难,我自己写一些使用CGI或URI的东西,但我想这种功能已经存在了。有什么建议么?
在:
http://example.com/path?param1=one¶m2=2¶m3=something3
日期:
http://example.com/path?param2=2¶m3=something3
我想从URL中取出一个参数,但不知道它是哪个参数,然后重新组装URL。Ruby中从URL中删除参数的最优雅方式是什么?
我想这并不难,我自己写一些使用CGI或URI的东西,但我想这种功能已经存在了。有什么建议么?
在:
http://example.com/path?param1=one¶m2=2¶m3=something3
日期:
http://example.com/path?param2=2¶m3=something3
的寻址创业板将很好地做到这一点;请看优秀回答者:田文。但是如果你想推出自己的产品,那么这就是如何。这段代码有高雅的唯一要求是,它隐藏丑陋的方法:
#!/usr/bin/ruby1.8
def reject_param(url, param_to_reject)
# Regex from RFC3986
url_regex = %r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$"
raise "Not a url: #{url}" unless url =~ url_regex
scheme_plus_punctuation = $1
authority_with_punctuation = $3
path = $5
query = $7
fragment = $9
query = query.split('&').reject do |param|
param_name = param.split(/[=;]/).first
param_name == param_to_reject
end.join('&')
[scheme_plus_punctuation, authority_with_punctuation, path, '?', query, fragment].join
end
url = "http://example.com/path?param1=one¶m2=2¶m3=something3"
p url
p reject_param(url, 'param2')
# => "http://example.com/path?param1=one¶m2=2¶m3=something3"
# => "http://example.com/path?param1=one¶m3=something3"
我想出了这样的事情
def uri_remove_param(uri, params = nil)
return uri unless params
params = Array(params)
uri_parsed = URI.parse(uri)
return uri unless uri_parsed.query
escaped = uri_parsed.query.grep(/&/).size > 0
new_params = uri_parsed.query.gsub(/&/, '&').split('&').reject { |q| params.include?(q.split('=').first) }
uri = uri.split('?').first
amp = escaped ? '&' : '&'
"#{uri}?#{new_params.join(amp)}"
end
我更喜欢使用:
require 'addressable/uri'
uri = Addressable::URI.parse('http://example.com/path?param1=one¶m2=2¶m3=something3')
params = uri.query_values #=> {"param1"=>"one", "param2"=>"2", "param3"=>"something3"}
params.delete('param1') #=> "one"
uri.query_values = params #=> {"param2"=>"2", "param3"=>"something3"}
uri.to_s #=> "http://example.com/path?param2=2¶m3=something3"
工作就像一个魅力! Github寻址地址:https://github.com/sporkmonger/addressable/tree/ – ankimal 2012-10-17 17:30:32
这比我的解决方案好得多。 – 2013-05-26 05:11:45
如果你不希望包括一个额外的宝石,如果你不想让讨厌的正则表达式,这里是我的首选方式:
require 'cgi'
require 'uri'
url = "http://example.com/path?param1=one¶m2=2¶m3=something3"
uri = URI(url) #=> #<URI::HTTP:0x007fbe25141a78 URL:http://example.com/path?param1=one¶m2=2¶m3=something3>
params = CGI.parse(uri.query || "") #=> {"param1"=>["one"], "param2"=>["2"], "param3"=>["something3"]}
params.delete('param1') #=> ["one"]
uri.query = URI.encode_www_form(params) #=> "param2=2¶m3=something3"
uri.to_s #=> "http://example.com/path?param2=2¶m3=something3"
+1使用stdlib – Puhlze 2013-05-26 05:43:14
我会修改CGI解析像这样处理缺少的参数...'CGI.parse(uri.query ||“”)'否则解析引发异常。 – 2016-02-05 20:58:36
一行应该是足够的:
url.sub(/\?param_to_remove=[^&]*/, '?').sub(/\¶m_to_remove=[^&]*/, '').sub(/\?$/,'')
正是我在找的东西!谢谢! – viniciusnz 2014-02-07 13:32:23
在param_to_remove第一次出现的情况下不正确 – 2017-05-03 08:49:11
Upvote使用RFC中的实际正则表达式。很好的参考。 – btelles 2010-01-27 23:50:11
分号也可以用来分隔查询参数,您的'reject_param'不适用于这个有效的URL'http://example.com/path?param1 = one; param2 = 2; param3 = something3'。 – 2010-11-24 20:09:25
@mu太短,谢谢。我修改了(但未经测试)代码以允许';'以及'='。 – 2010-11-24 21:30:52