将绝对路径转换为相对路径

3

将相对路径 foo 相对于参考点 bar 转换为绝对路径 baz 可以通过以下方式完成:

baz = File.expand_path(foo, bar)

如何实现相反的操作呢?换句话说,给定一个绝对路径 baz 和参考点 bar(以绝对路径的形式给出),如何将其转换为下面的相对路径 foo

foo = File.relative_path(baz, bar)

请假设所有给定的路径都已标准化,即在它们表示目录时不以/结尾:
"/foo/bar"
"/foo/bar/" # No need to consider

同样的原理也适用于所有返回路径。

请注意,这并不像简单地从baz的初始部分中剥离掉bar并用./替换它那么简单,因为baz不一定是bar的后代。一般来说,需要堆叠多个../才能到达共同的祖先。

例子包括但不限于:

File.relative_path("/foo/bar/quex", "/foo") # => "bar/quex" (preferred) or
                                            #    "./bar/quex"
File.relative_path("/foo", "/foo/bar") # => "../"
File.relative_path("/foo/bar", "/baz/quex") # => "../../foo/bar"

哇哦.. 这是一个多么棒的想法.. +1 - Arup Rakshit
1
它是出于必要而产生的,不仅仅是出于好奇心。 :) - sawa
1
呵呵……还是不错的……哇塞……你做得很好。我认为,如果你真的能给出一些真实路径作为例子,那会很好。这样我/我们就可以更好地理解你的需求。 - Arup Rakshit
1
为什么对这篇帖子进行 关闭投票 - Arup Rakshit
1个回答

9

我相信你需要的是Pathname#relative_path_from方法。可以参考我之前回答另一个问题的答案

require 'pathname'

first = Pathname.new '/first/path'
second = Pathname.new '/second/path'

relative = second.relative_path_from first
# ../../second/path

first + relative
# /second/path

1
谢谢。它很有帮助。只是为了以后参考其他人:应该将 to_s 应用于结果。 - sawa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接