【问题标题】:How to obtain the last path segment of a URI如何获取 URI 的最后一个路径段
【发布时间】:2011-05-02 07:04:12
【问题描述】:

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

这是我的输入网址:

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();

但它不起作用,肯定有更好的方法来做到这一点。

【问题讨论】:

  • 方法getLastPathSegment 不适用于Android 6.0 中的:

标签: java string url


【解决方案1】:

这就是你要找的东西:

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);

【讨论】:

  • 我正在搜索 Android 的 android.net.Uri(不是 java.net.URI)并最终到了这里。如果您改用它,则有一个名为 getLastPathSegment() 的方法应该做同样的事情。 :)
  • 只做String idStr = new File(uri.getPath()).getName(),和这个答案一样,但是使用File而不是String来分割路径。
  • 这不适用于像example.com/job/senior-health-and-nutrition-advisor/?param=true 这样的网址。最后一个“/”很麻烦。需要更好的东西 @paul_sns 给出的 getLastPathSegment() 答案是完美的。
  • @VaibhavKadam 好吧,从技术上讲,您可以争辩说最后一段是空字符串。但如果这不是您想要的,只需使用:while (path.endsWith("/")) path = path.substring(0, path.length() - 1);
  • @sfussenegger 很糟糕,我没有阅读有问题的标签。我以为它有android的标签。 android.net.uri 的 +1。 :)。 Android 正在接管 JAVA。
【解决方案2】:
import android.net.Uri;
Uri uri = Uri.parse("http://example.com/foo/bar/42?param=true");
String token = uri.getLastPathSegment();

【讨论】:

  • 这是“android.net.Uri”吗?基于问题的标签,将假定 java.net.URI 并且它没有 getLastPathSegment()...
  • 另外,Android Uri 类名是小写的,不能实例化。我已更正您使用静态工厂方法Uri.parse() 的答案。
  • GetLastPathSegment 在这里不存在。
  • 它确实有 getLastPathSegment() 但它不起作用!返回 null!
  • 似乎 getLastPathSegment() 为我随机吐出完整路径。
【解决方案3】:

这是一个简短的方法:

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

酒吧

解释:

.*/      // 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 几乎是最迟钝的。它并不简单,因为它没有被快速理解。
  • 否定字符类[^/?]中的/是不必要的,因为它永远不会被匹配。 .*/ 将始终匹配字符串中的 last /,因此不应遇到其他 /
  • 不适用于这种链接http://example.com/foo#reply2,如果你能更新你的答案来解决它,那就太好了。谢谢
  • @Seth 我自己刚刚尝试过;如果您将正则表达式更新为 ([^#/?]+) 而不是 ([^/?]+) 应该可以工作。
【解决方案4】:

我知道这是旧的,但这里的解决方案似乎相当冗长。如果您有URLURI,则只是一个易于阅读的单行:

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).
  • @alik 该问题要求提供最后一个路径段。查询和片段不是路径段的一部分。
【解决方案5】:

如果您使用的是 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);

【讨论】:

  • 有风险,因为 java.nio.file.Paths#get 依赖于运行 JVM 的操作系统文件系统。不能保证它会识别带有正斜杠的 URI 作为路径分隔符。
  • 带有查询参数的 URI 怎么样?将随机 URI 视为文件系统路径是在请求异常。
【解决方案6】:

在 Android 中

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

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

【讨论】:

  • 有时这只是吐出完整路径。不知道为什么或何时它似乎是随机的。
  • 如果你能捕捉到它正在解析的内容,也许你可以设置一个单元测试来确保。
【解决方案7】:

在 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() 将检索倒数第三个段。

【讨论】:

    【解决方案8】:

    如果您的项目中包含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

    【讨论】:

      【解决方案9】:

      你也可以使用replaceAll:

      String uri = "http://base_path/some_segment/id"
      String lastSegment = uri.replaceAll(".*/", "")
      
      System.out.println(lastSegment);
      

      结果:

      id
      

      【讨论】:

        【解决方案10】:

        您可以使用getPathSegments() 函数。 (Android Documentation)

        考虑您的示例 URI:

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

        您可以使用以下方法获取最后一段:

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

        lastSegment 将是 id

        【讨论】:

          【解决方案11】:

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

          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();
          }
          

          【讨论】:

            【解决方案12】:

            您可以从 Uri 类中获取路径段列表

            String id = Uri.tryParse("http://base_path/some_segment/id")?.pathSegments.last ?? "InValid URL";
            

            如果url有效则返回id,如果无效则返回"Invalid url"

            【讨论】:

              【解决方案13】:

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

              【讨论】:

              • 不起作用,请参阅 getFile() 的 javadoc:获取此 URL 的文件名。返回的文件部分将与 getPath() 相同,加上 getQuery() 值的串联(如果有)。如果没有查询部分,此方法和 getPath() 将返回相同的结果。)
              • 使用getPath() 而不是getFile()
              猜你喜欢
              • 2020-04-13
              • 1970-01-01
              • 1970-01-01
              • 2012-11-30
              • 1970-01-01
              • 2015-11-24
              • 2019-07-24
              • 2012-03-02
              • 2013-11-15
              相关资源
              最近更新 更多