Учитывая два абсолютных URI, найдите относительный путь между ними - PullRequest
0 голосов
/ 13 сентября 2018

Есть ли в стандартной библиотеке 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 голосов
/ 13 сентября 2018

Оказывается, пакет path/filepath может сделать это за вас. Если вы игнорируете тот факт, что это 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 , чтобы сначала проанализировать путь как 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 "../.."
...