Ruby中从URL中删除参数的最优雅方式是什么?

dim*_*mus 14 ruby url parsing

我想从URL中取出一个参数,而不知道它是哪个参数,然后重新组合URL.

我想使用CGI或URI自己写一些东西并不难,但我想这样的功能已经存在.有什么建议?

在:

http://example.com/path?param1=one&param2=2&param3=something3
Run Code Online (Sandbox Code Playgroud)

日期:

http://example.com/path?param2=2&param3=something3
Run Code Online (Sandbox Code Playgroud)

the*_*Man 35

我更喜欢使用:

require 'addressable/uri'

uri = Addressable::URI.parse('http://example.com/path?param1=one&param2=2&param3=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&param3=something3"
Run Code Online (Sandbox Code Playgroud)

  • 这比我的解决方案好得多. (2认同)

fra*_*ous 26

也许有点偏离主题,但对于那些试图在rails应用程序环境中执行此操作的人,您可以简单地执行以下操作:

url_for(params.except(:name_of_param_to_delete))
Run Code Online (Sandbox Code Playgroud)

NB在rails v2.3.9中测试过.


Rob*_*ert 16

如果你不想包含一个额外的宝石,如果你不想要讨厌的正则表达式,这是我的首选方式:

require 'cgi'
require 'uri'

url = "http://example.com/path?param1=one&param2=2&param3=something3"

uri = URI(url) #=> #<URI::HTTP:0x007fbe25141a78 URL:http://example.com/path?param1=one&param2=2&param3=something3>
params = Rack::Utils.parse_nested_query(uri.query || "") #=> {"param1"=>["one"], "param2"=>["2"], "param3"=>["something3"]}
params.delete('param1') #=> ["one"]
uri.query = URI.encode_www_form(params) #=> "param2=2&param3=something3"

uri.to_s #=> "http://example.com/path?param2=2&param3=something3"
Run Code Online (Sandbox Code Playgroud)

  • 我会像这样修改CGI解析来处理丢失的参数...`CGI.parse(uri.query ||"")`否则解析会引发异常. (2认同)

Way*_*rad 8

寻址创业板将做到这一点很好; 请看The Tin Man的优秀答案.但是如果你想自己动手,那就是这样的.这个代码唯一的优点是它隐藏了一个方法中的丑陋:

#!/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&param2=2&param3=something3"
p url
p reject_param(url, 'param2')

# => "http://example.com/path?param1=one&param2=2&param3=something3"
# => "http://example.com/path?param1=one&param3=something3"
Run Code Online (Sandbox Code Playgroud)

  • Upvote使用RFC的实际正则表达式.很好的参考. (2认同)
  • 分号也可用于分隔查询参数,你的`reject_param`不适用于这个有效的URL`http://example.com/path?param1 = one; param2 = 2; param3 = something3`. (2认同)

dim*_*mus 5

我想出了类似的东西

 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(/&amp;/).size > 0
   new_params = uri_parsed.query.gsub(/&amp;/, '&').split('&').reject { |q| params.include?(q.split('=').first) }
   uri = uri.split('?').first
   amp = escaped ? '&amp;' : '&'
   "#{uri}?#{new_params.join(amp)}"
 end
Run Code Online (Sandbox Code Playgroud)