17

我必须向不确定的 URL 添加一个新参数,比如说param=value.

如果实际的 URL 已经有这样的参数

http://url.com?p1=v1&p2=v2

我应该将 URL 转换为另一个:

http://url.com?p1=v1&p2=v2&param=value

但是如果 URL 还没有任何参数,像这样:

http://url.com

我应该将 URL 转换为另一个:

http://url.com?param=value

我担心用正则表达式解决这个问题,因为我不确定寻找 的存在&是否足够。我在想也许我应该将 URL 转换为URI对象,然后添加参数并将其再次转换为 String。

寻找已经处于这种情况的人的任何建议。

更新

为了帮助参与,我分享了一个基本的测试套件:

require "minitest"
require "minitest/autorun"

def add_param(url, param_name, param_value)
  # the code here
  "not implemented"
end

class AddParamTest < Minitest::Test
  def test_add_param
    assert_equal("http://url.com?param=value", add_param("http://url.com", "param", "value"))
    assert_equal("http://url.com?p1=v1&p2=v2&param=value", add_param("http://url.com?p1=v1&p2=v2", "param", "value"))
    assert_equal("http://url.com?param=value#&tro&lo&lo", add_param("http://url.com#&tro&lo&lo", "param", "value"))
    assert_equal("http://url.com?p1=v1&p2=v2&param=value#&tro&lo&lo", add_param("http://url.com?p1=v1&p2=v2#&tro&lo&lo", "param", "value"))
  end
end
4

4 回答 4

30
require 'uri'

uri = URI("http://url.com?p1=v1&p2=2")
ar = URI.decode_www_form(uri.query) << ["param","value"]
uri.query = URI.encode_www_form(ar)
p uri #=> #<URI::HTTP:0xa0c44c8 URL:http://url.com?p1=v1&p2=2&param=value>

uri = URI("http://url.com")
uri.query = "param=value" if uri.query.nil?
p uri #=> #<URI::HTTP:0xa0eaee8 URL:http://url.com?param=value>

编辑:(由 fguillen 合并所有好的命题,并使其与他的问题测试套件兼容。)

require 'uri'

def add_param(url, param_name, param_value)
  uri = URI(url)
  params = URI.decode_www_form(uri.query || "") << [param_name, param_value]
  uri.query = URI.encode_www_form(params)
  uri.to_s
end
于 2013-05-18T11:29:58.523 回答
2

更优雅的解决方案:

url       = 'http://example.com?exiting=0'
params    = {new_param: 1}
uri       = URI.parse url
uri.query = URI.encode_www_form URI.decode_www_form(uri.query || '').concat(params.to_a)
uri.to_s #=> http://example.com?exiting=0&new_param=1
于 2017-03-03T12:58:28.387 回答
1

好吧,你可能也不知道 url 中是否已经存在这个参数。如果你想在这种情况下用新值替换它,你可以这样做:

url = 'http://example.com?exists=0&other=3'
params = {'exists' => 1, "not_exists" => 2}
uri = URI.parse url
uri.query = URI.encode_www_form(URI.decode_www_form(uri.query || '').to_h.merge(params))
uri.to_s
于 2020-05-08T18:57:34.110 回答
0

您可以尝试使用我的 gem iri

Iri.new('http://url.com?p1=v1&p2=v2').add(:param, 'value').to_s
于 2021-06-14T14:08:53.133 回答