给定两个绝对URI,找到它们之间的相对路径

时间:2018-09-13 03:20:57

标签: go url-parsing

go标准库中是否有一个函数可以让我做到这一点

a = 'www.my.com/your/stuff'
b = 'www.my.com/your/stuff/123/4'

function(b,a) // /123/4 

function(URL(b),URL(a)) // /123/4

在这种情况下,可能定义了以下内容

function(a,b) // error ? or ../../

我知道我可以使用path软件包。但是在有查询参数,文件扩展名等的许多情况下,它无法工作。

基本上,我正在寻找path.resolve对应的URL

1 个答案:

答案 0 :(得分:2)

事实证明,path/filepath package可以为您做到这一点。如果您忽略了这些是URL的事实,而是将它们视为路径,则可以使用filepath.Rel()

package main

import (
    "fmt"
    "path/filepath"
)

func main() {
    base := "www.my.com/your/stuff"
    target := "www.my.com/your/stuff/123/4"
    rel, _ := filepath.Rel(base, target)
    fmt.Println(rel) // prints "123/4"
}

游乐场:https://play.golang.org/p/nnF9zfFAFfc

如果要将这些路径视为实际URL,则可能应该使用net/url package首先将路径解析为URL,然后提取路径并在其上使用filepath.Rel()。这样,您就可以正确处理诸如URL字符串中的查询之类的问题,这可能会使filepath跳闸,如下所示:

package main

import (
    "fmt"
    "path/filepath"
    "net/url"
)

func main() {
    url1, _ := url.Parse("http://www.my.com/your/stuff")
    url2, _ := url.Parse("http://www.my.com/your/stuff/123/4?query=test")

    base := url1.Path
    target := url2.Path

    rel, _ := filepath.Rel(base, target)
    fmt.Println(base)   // "/your/stuff"
    fmt.Println(target) // "/your/stuff/123/4"
    fmt.Println(rel)    // "123/4"
}

游乐场:https://play.golang.org/p/gnZfk0t8GOZ

作为奖励,filepath.Rel()也足够聪明,可以处理另一个方向的相对路径:

rel, _ = filepath.Rel(target, base) // rel is now "../.."