在Java中从一个URL到另一个URL找到相对路径

Find relative path from one URL to another in Java

本问题已经有最佳答案,请猛点这里访问。

给定两条路径,如何计算从一条到另一条的相对路径?

我曾想过用花哨的方式使用split,但它似乎有点黑客,特别是在像"http://foo.com/bar/baz#header""http://foo.com/bar/baz"?param=value这样的情况下。

例如:

1
2
3
4
String url1 ="http://foo.com/bar/baz";
String url2 ="http://foo.com/bar/qux/quux/corge";

System.out.println(relative(url1, url2)); // ->"../qux/quux/corge"


Java已经提供了这个功能,所以最安全的选择是采用"标准"方式:

1
2
3
4
5
6
7
8
String url1 ="http://foo.com/bar/baz";
String url2 ="http://foo.com/bar/qux/quux/corge";

Path p1 = Paths.get(url1);
Path p2 = Paths.get(url2);
Path p  = p1.relativize(p2);

System.out.println("Relative path:" + p);

上面的print语句显示了正确的相对路径,在这种情况下,

1
../qux/quux/corge

如果协议(如http vs https)和主机部分可能不同,那么将上面的url1url2转换成URLobjectsand using thegetpath()方法,应该产生正确的相对路径。


不管你用的是什么黑客方法,它都必须在引擎盖下循环访问你的URL。indexof()、split()和其他查找字符的函数仍然有O(n)运行时,因为它们需要查找这些字符。所以,您也可以编写自己的"indexof"样式函数。只需比较每个字符,一次一个,直到找到不同之处。这标志着相同URL的结束,并且由于我们可以在循环之外偷偷地声明"i",所以我们可以退出循环,并保留该索引。然后你只需把剩下的长网址吐出来!

1
2
3
4
5
6
7
8
9
10
public String relative (String url1, String url2) {
    int i;
    for(i = 0; i < url1.length(); i++) {
        if(url1.charAt(i) != url2.charAt(i))
            break;
    }
    if(url1.length() > url2.length())
        return url1.substring(i);
    return url2.substring(i);
}


你可以这样做:

1
2
3
4
5
6
7
8
9
10
public static String relative(String url1, String url2){
    String[] parts = url1.split("/");
    String similar ="";
    for(String part:parts){
        if(url2.contains(similar+part+"/")){
            similar+=part+"/";
        }
    }
    return"./"+url2.replace(similar,"");
}