如何获取URI的最后一个路径段


114

我输入的是一个字符串URI。如何获得最后的路径段(在我的情况下是id)?

这是我的输入URL:

String uri = "http://base_path/some_segment/id"

我必须获得我尝试过的ID:

String strId = "http://base_path/some_segment/id";
strId = strId.replace(path);
strId = strId.replaceAll("/", "");
Integer id =  new Integer(strId);
return id.intValue();

但这是行不通的,并且肯定有更好的方法可以做到这一点。

Answers:


174

是您要寻找的:

URI uri = new URI("http://example.com/foo/bar/42?param=true");
String path = uri.getPath();
String idStr = path.substring(path.lastIndexOf('/') + 1);
int id = Integer.parseInt(idStr);

或者

URI uri = new URI("http://example.com/foo/bar/42?param=true");
String[] segments = uri.getPath().split("/");
String idStr = segments[segments.length-1];
int id = Integer.parseInt(idStr);

49
我正在搜索Android的android.net.Uri(不是java.net.URI),并最终到了这里。如果使用的是,则有一个名为getLastPathSegment()的方法应该执行相同的操作。:)
pm_labs 2013年

5
只需做String idStr = new File(uri.getPath()).getName(),与此答案相同,但使用File而不是String分割路径。
杰森C

这不适用于example.com/job/senior-health-and-nutrition-advisor/?param=true之类的网址。最后的“ /”麻烦了。需要更多更好的由@paul_sns给出的getLastPathSegment()答案是完美的。
Vaibhav Kadam

@VaibhavKadam很好,从技术上讲,您可以说最后一段是空字符串。但是,如果那不是您想要的,则只需使用:while (path.endsWith("/")) path = path.substring(0, path.length() - 1);
sfussenegger

@sfussenegger很抱歉,我没有阅读相关的TAG。我以为它有android的标签。+1为android.net.uri。:)。Android正在接管JAVA。
Vaibhav Kadam

69
import android.net.Uri;
Uri uri = Uri.parse("http://example.com/foo/bar/42?param=true");
String token = uri.getLastPathSegment();

1
这是“ android.net.Uri”吗?假设问题的标签是java.net.URI,并且没有getLastPathSegment()...
Michael Geiser 2015年

另外,Android Uri类名是小写的,无法实例化。我已纠正您使用静态工厂方法的答案Uri.parse()
2015年

GetLastPathSegment在这里不存在。
Abdullah Shoaib 2015年

2
它确实具有getLastPathSegment(),但不起作用!返回null!
朱尼亚·蒙大纳州

好像getLastPathSegment()随机为我吐出了完整路径。
MobDev

48

这是一个简短的方法:

public static String getLastBitFromUrl(final String url){
    // return url.replaceFirst("[^?]*/(.*?)(?:\\?.*)","$1);" <-- incorrect
    return url.replaceFirst(".*/([^/?]+).*", "$1");
}

测试代码:

public static void main(final String[] args){
    System.out.println(getLastBitFromUrl(
        "http://example.com/foo/bar/42?param=true"));
    System.out.println(getLastBitFromUrl("http://example.com/foo"));
    System.out.println(getLastBitFromUrl("http://example.com/bar/"));
}

输出:

42
FOO
酒吧

说明:

.*/      // find anything up to the last / character
([^/?]+) // find (and capture) all following characters up to the next / or ?
         // the + makes sure that at least 1 character is matched
.*       // find all following characters


$1       // this variable references the saved second group from above
         // I.e. the entire string is replaces with just the portion
         // captured by the parentheses above

虽然我是regex的忠实拥护者,并且自己经常使用它,但我认识到,对于大多数开发人员而言,regex几乎是一成不变的。事实并不容易理解,这并不简单。
比尔·特纳

/在否定字符类[^/?]是不必要的,因为它永远不会匹配。.*/将始终匹配字符串中的最后一个 /,因此不会/遇到其他任何情况。
Stefan van den Akker's

不适用于这种链接http://example.com/foo#reply2,如果您可以更新答案来解决它,那就太好了。谢谢
赛斯(Seth)

23

我知道这很老,但是这里的解决方案似乎很冗长。如果您有URL或,则只是一个易于阅读的单行代码URI

String filename = new File(url.getPath()).getName();

或者,如果您有String

String filename = new File(new URL(url).getPath()).getName();

它可以与URL的所有可能选项一起使用吗a.co/last?a=1#frag?我认为不行,因为代码会将最后一个路径符号的子字符串保留到结尾:path.substring(index + 1)
AlikElzin-kilaka

4
@alik问题要求最后一个路径段。查询和片段不是路径段的一部分。
詹森·C

13

如果您正在使用Java 8,并且想要文件路径中的最后一段,则可以执行。

Path path = Paths.get("example/path/to/file");
String lastSegment = path.getFileName().toString();

如果您有这样的网址,http://base_path/some_segment/id可以这样做。

final Path urlPath = Paths.get("http://base_path/some_segment/id");
final Path lastSegment = urlPath.getName(urlPath.getNameCount() - 1);

4
冒险,因为java.nio.file.Paths#get取决于运行JVM的OS文件系统。不能保证它将识别带有正斜杠的URI作为路径分隔符。
阿德里安·贝克

2
带有查询参数的URI呢?将随机URI视为文件系统路径要求异常。
Abhijit Sarkar

9

在Android中

Android具有用于管理URI的内置类。

Uri uri = Uri.parse("http://base_path/some_segment/id");
String lastPathSegment = uri.getLastPathSegment()

有时,这只是吐出了完整的路径。不知道为什么或何时似乎是随机的。
MobDev

如果可以捕获正在解析的内容,则可以设置一个单元测试来确保。
Brill Pappin

8

在Java 7+中,可以结合使用一些先前的答案,以允许从URI中检索任何路径段,而不仅仅是最后一个段。我们可以将URI转换为java.nio.file.Path对象,以利用其getName(int)方法。

不幸的是,静态工厂Paths.get(uri)不是为处理http方案而构建的,因此我们首先需要将该方案与URI的路径分开。

URI uri = URI.create("http://base_path/some_segment/id");
Path path = Paths.get(uri.getPath());
String last = path.getFileName().toString();
String secondToLast = path.getName(path.getNameCount() - 2).toString();

要获得一行代码中的最后一段,只需将上面的行嵌套。

Paths.get(URI.create("http://base_path/some_segment/id").getPath()).getFileName().toString()

若要获得倒数第二个分段,同时避免使用索引号和可能出现的错误,请使用getParent()方法。

String secondToLast = path.getParent().getFileName().toString();

请注意,getParent()可以重复调用此方法以相反的顺序检索段。在此示例中,路径仅包含两个段,否则调用getParent().getParent()将检索倒数第二个段。


6

如果您已将其commons-io包含在项目中,则无需使用以下方法创建不必要的对象org.apache.commons.io.FilenameUtils

String uri = "http://base_path/some_segment/id";
String fileName = FilenameUtils.getName(uri);
System.out.println(fileName);

将为您提供路径的最后一部分,即 id


3

您可以使用getPathSegments()功能。(Android文档

考虑您的示例URI:

String uri = "http://base_path/some_segment/id"

您可以使用以下方法获取最后一个细分:

List<String> pathSegments = uri.getPathSegments();
String lastSegment = pathSegments.get(pathSegments.size - 1);

lastSegment将会id



0

我在实用程序类中使用以下内容:

public static String lastNUriPathPartsOf(final String uri, final int n, final String... ellipsis)
  throws URISyntaxException {
    return lastNUriPathPartsOf(new URI(uri), n, ellipsis);
}

public static String lastNUriPathPartsOf(final URI uri, final int n, final String... ellipsis) {
    return uri.toString().contains("/")
        ? (ellipsis.length == 0 ? "..." : ellipsis[0])
          + uri.toString().substring(StringUtils.lastOrdinalIndexOf(uri.toString(), "/", n))
        : uri.toString();
}

-1

从URI获取URL,如果还没有准备好使用子字符串提取文件的方法,请使用getFile()。


2
无效,请参见getFile()的javadoc:获取此URL的文件名。返回的文件部分将与getPath()相同,再加上getQuery()值的串联(如果有)。如果没有查询部分,则此方法和getPath()将返回相同的结果。)
sfussenegger 2010年

getPath()不要使用getFile()
杰森C
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.