duanli5662
2018-09-13 03:20
浏览 38
已采纳

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

Is there a function in go standard library that lets me do this

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

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

or

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

The following is probably defined in this case

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

I'm aware that I can use path package for this. But it cannot work in many cases where there is query param, file extension etc.

Basically I'm looking for a path.resolve counterpart for URL

图片转代码服务由CSDN问答提供 功能建议

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

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

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

 功能(URL(b),URL(a))// / 123/4 \  n   
 
 

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

  function(a,b)//错误? 或../../ 
   
 
 

我知道我可以为此使用 path 包。 但这在存在查询参数,文件扩展名等的许多情况下不起作用。

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

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • douchen7555 2018-09-13 03:44
    已采纳

    It turns out that the path/filepath package can do this for you. If you ignore the fact that these are URLs and instead treat them like paths, you can use 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"
    }
    

    Playground: https://play.golang.org/p/nnF9zfFAFfc

    If you want to treat these paths as actual URLs, you should probably use the net/url package to first parse the path as a URL, then extract the path and use filepath.Rel() on that. This allows you to properly deal with things like queries in the URL string, which would trip up filepath, like so:

    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"
    }
    

    Playground: https://play.golang.org/p/gnZfk0t8GOZ

    As a bonus, filepath.Rel() is smart enough to handle relative paths in the other direction, too:

    rel, _ = filepath.Rel(target, base) // rel is now "../.."
    
    打赏 评论

相关推荐 更多相似问题