我试图找到一种将部分url路径段连接在一起的可靠方法.有快速的方法吗?
我尝试了以下方法:
puts URI::join('resource/', '/edit', '12?option=test')
Run Code Online (Sandbox Code Playgroud)
我预计:
resource/edit/12?option=test
Run Code Online (Sandbox Code Playgroud)
但我得到错误:
`merge': both URI are relative (URI::BadURIError)
Run Code Online (Sandbox Code Playgroud)
我File.join()过去曾经使用过这个,但是对于使用url文件库来说似乎并不正确.
jro*_*ind 21
URI的api并不是很好.
URI :: join只有在第一个以协议开头的绝对uri时才有效,而后者以正确的方式相对...除了我尝试这样做,甚至无法让它工作.
这至少没有错误,但为什么它会跳过中间组件?
URI::join('http://somewhere.com/resource', './edit', '12?option=test')
Run Code Online (Sandbox Code Playgroud)
我想也许URI有点糟透了.它在实例上缺少重要的api,例如实例#join或相对于基本uri的方法,你期望它.这有点糟糕.
我想你将不得不自己写.或者只是使用File.join和其他文件路径方法,在测试了所有可以想到的边缘情况后,确保它能够满足您的需求.
编辑 2016年12月9日我发现可寻址的宝石非常好.
base = Addressable::URI.parse("http://example.com")
base + "foo.html"
# => #<Addressable::URI:0x3ff9964aabe4 URI:http://example.com/foo.html>
base = Addressable::URI.parse("http://example.com/path/to/file.html")
base + "relative_file.xml"
# => #<Addressable::URI:0x3ff99648bc80 URI:http://example.com/path/to/relative_file.xml>
base = Addressable::URI.parse("https://example.com/path")
base + "//newhost/somewhere.jpg"
# => #<Addressable::URI:0x3ff9960c9ebc URI:https://newhost/somewhere.jpg>
base = Addressable::URI.parse("http://example.com/path/subpath/file.html")
base + "../up-one-level.html"
=> #<Addressable::URI:0x3fe13ec5e928 URI:http://example.com/path/up-one-level.html>
Run Code Online (Sandbox Code Playgroud)
将 uri 作为URI::Generic或它的子类
uri.path += '/123'
Run Code Online (Sandbox Code Playgroud)
享受!
2016 年 6 月 25 日对持怀疑态度的人的更新
require 'uri'
uri = URI('http://ioffe.net/boris')
uri.path += '/123'
p uri
Run Code Online (Sandbox Code Playgroud)
输出
<URI::HTTP:0x2341a58 URL:http://ioffe.net/boris/123>
Run Code Online (Sandbox Code Playgroud)
问题是resource/相对于当前目录,但/edit由于前导斜杠而引用顶级目录.如果没有确切知道edit包含这两个目录,就不可能加入这两个目录resource.
如果您正在寻找纯粹的字符串操作,只需从所有部分中删除前导或尾部斜杠,然后将它们/作为粘合剂连接起来.
使用URI.join的方法是:
URI.join('http://example.com', '/foo/', 'bar')
注意尾随斜杠.您可以在此处找到完整的文档:
http://www.ruby-doc.org/stdlib-1.9.3/libdoc/uri/rdoc/URI.html#method-c-join
正如您所注意到的,URI::join不会将路径与重复的斜杠组合在一起,因此它不适合该部分。
事实证明,它不需要很多 Ruby 代码来实现这一点:
module GluePath
def self.join(*paths, separator: '/')
paths = paths.compact.reject(&:empty?)
last = paths.length - 1
paths.each_with_index.map { |path, index|
_expand(path, index, last, separator)
}.join
end
def self._expand(path, current, last, separator)
if path.start_with?(separator) && current != 0
path = path[1..-1]
end
unless path.end_with?(separator) || current == last
path = [path, separator]
end
path
end
end
Run Code Online (Sandbox Code Playgroud)
该算法处理连续斜线,保留开始和结束斜线,并忽略nil和空字符串。
puts GluePath::join('resource/', '/edit', '12?option=test')
Run Code Online (Sandbox Code Playgroud)
产出
resource/edit/12?option=test
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24619 次 |
| 最近记录: |