Cách lấy đoạn đường dẫn cuối cùng của URI


114

Tôi có đầu vào là một chuỗi là a URI. Làm cách nào để có được đoạn đường dẫn cuối cùng (trong trường hợp của tôi là id)?

Đây là URL đầu vào của tôi:

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

và tôi phải lấy id mà tôi đã thử với cái này:

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

nhưng nó không hoạt động, và chắc chắn phải có một cách tốt hơn để làm điều đó.

Câu trả lời:


174

Có phải đó là những gì bạn đang tìm kiếm:

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

cách khác

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
Tôi đã tìm kiếm android.net.Uri của Android (không phải java.net.URI) và kết thúc ở đây. Nếu bạn đang sử dụng phương thức đó thay vào đó, có một phương thức được gọi là getLastPathSegment () sẽ làm điều tương tự. :)
pm_labs

5
Just do String idStr = new File(uri.getPath()).getName(), giống như câu trả lời này nhưng sử dụng Filethay vì Stringđể chia đường dẫn.
Jason C

điều này sẽ không hoạt động đối với các url như example.com/job/senior-health-and-osystem-advisor/?param=true . Cuối cùng "/" đang gây ra sự cố. Cần một cái gì đó tốt hơn câu trả lời getLastPathSegment () do @paul_sns đưa ra là hoàn hảo.
Vaibhav Kadam

@VaibhavKadam tốt, về mặt kỹ thuật, bạn có thể tranh luận rằng phân đoạn cuối cùng là một chuỗi rỗng. Nhưng nếu đó không phải những gì bạn muốn chỉ cần sử dụng:while (path.endsWith("/")) path = path.substring(0, path.length() - 1);
sfussenegger

@sfussenegger Thật tệ là tôi đã không đọc các TAG được đề cập. Tôi nghĩ rằng nó có thẻ của android. Cũng +1 cho android.net.uri. :). Android đang tiếp quản 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
Đây có phải là "android.net.Uri" không? Căn cứ không có các thẻ của câu hỏi, java.net.URI sẽ được giả định và nó không có getLastPathSegment () ...
Michael Geiser

Ngoài ra, Uritên lớp Android là chữ thường và không thể khởi tạo được. Tôi đã sửa câu trả lời của bạn để sử dụng phương pháp nhà máy tĩnh Uri.parse().
yên tĩnh

GetLastPathSegment không tồn tại ở đây.
Abdullah Shoaib

2
nó có getLastPathSegment () nhưng nó không hoạt động! trả về null!
Junia Montana

Có vẻ như getLastPathSegment () ngẫu nhiên tạo ra đường dẫn đầy đủ cho tôi.
MobDev

48

Đây là một phương pháp ngắn để làm điều đó:

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

Mã kiểm tra:

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/"));
}

Đầu ra:

42
foo
bar

Giải trình:

.*/      // 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

trong khi tôi là một người hâm mộ lớn của regex và thường xuyên sử dụng nó, tôi nhận ra rằng đối với hầu hết các nhà phát triển, regex cũng khá là khó hiểu. nó không đơn giản hơn trong thực tế là nó không được hiểu nhanh chóng.
Bill Turner

Trong /lớp ký tự bị phủ định [^/?]là không cần thiết, vì nó sẽ không bao giờ được so khớp. .*/sẽ luôn khớp với chuỗi cuối cùng / trong Chuỗi, vì vậy không /nên gặp phải chuỗi nào khác .
Stefan van den Akker

không hoạt động cho loại liên kết này http://example.com/foo#reply2, Sẽ thật tuyệt nếu bạn có thể cập nhật câu trả lời của mình để giải quyết nó. Cảm ơn
Seth

23

Tôi biết điều này là cũ, nhưng các giải pháp ở đây có vẻ khá dài dòng. Chỉ là một dòng lót dễ đọc nếu bạn có URLhoặc URI:

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

Hoặc nếu bạn có String:

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

Nó có hoạt động với tất cả các tùy chọn có thể có của một URL không, chẳng hạn như a.co/last?a=1#frag. Tôi nghĩ rằng không, vì mã không substring của biểu tượng con đường cuối cùng cho đến khi cuối cùng: path.substring(index + 1).
AlikElzin-kilaka

4
@alik Câu hỏi yêu cầu phân đoạn đường dẫn cuối cùng. Truy vấn và phân đoạn không phải là một phần của phân đoạn đường dẫn.
Jason C

13

Nếu bạn đang sử dụng Java 8 và bạn muốn phân đoạn cuối cùng trong đường dẫn tệp, bạn có thể thực hiện.

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

Nếu bạn có một url chẳng hạn như http://base_path/some_segment/idbạn có thể làm.

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

4
Rủi ro vì java.nio.file.Paths # nhận được phụ thuộc vào hệ thống tệp hệ điều hành mà JVM đang chạy. Không có gì đảm bảo rằng nó sẽ nhận ra một URI với các dấu gạch chéo về phía trước làm dấu phân cách đường dẫn.
Adrian Baker

2
Còn URI với các tham số truy vấn thì sao? Xử lý một URI ngẫu nhiên như một đường dẫn hệ thống tệp yêu cầu một ngoại lệ.
Abhijit Sarkar

9

Trong Android

Android có một lớp tích hợp để quản lý URI.

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

Đôi khi điều này chỉ tạo ra đường dẫn đầy đủ. Không chắc tại sao hoặc khi nào nó có vẻ là ngẫu nhiên.
MobDev

Nếu bạn có thể nắm bắt được nội dung mà nó đang phân tích cú pháp, có thể bạn có thể thiết lập một bài kiểm tra đơn vị để đảm bảo.
Brill Pappin

8

Trong Java 7+, một số câu trả lời trước đó có thể được kết hợp để cho phép truy xuất bất kỳ đoạn đường dẫn nào từ URI, thay vì chỉ đoạn cuối cùng. Chúng ta có thể chuyển đổi URI thành một java.nio.file.Pathđối tượng, để tận dụng getName(int)phương thức của nó .

Thật không may, nhà máy tĩnh Paths.get(uri)không được xây dựng để xử lý lược đồ http, vì vậy trước tiên chúng ta cần tách lược đồ khỏi đường dẫn của 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();

Để lấy phân đoạn cuối cùng trong một dòng mã, chỉ cần lồng các dòng ở trên.

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

Để có được phân đoạn từ thứ hai đến cuối cùng trong khi tránh các số chỉ mục và khả năng xảy ra lỗi riêng lẻ, hãy sử dụng getParent()phương pháp này.

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

Lưu ý rằng getParent()phương thức có thể được gọi nhiều lần để truy xuất các phân đoạn theo thứ tự ngược lại. Trong ví dụ này, đường dẫn chỉ chứa hai phân đoạn, nếu không việc gọi getParent().getParent()sẽ truy xuất phân đoạn từ thứ ba đến cuối cùng.


6

Nếu bạn đã commons-iođưa vào dự án của mình, bạn có thể làm điều đó mà không cần tạo các đối tượng không cần thiết vớiorg.apache.commons.io.FilenameUtils

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

Sẽ cung cấp cho bạn phần cuối cùng của con đường, đó là id


3

Bạn có thể sử dụng getPathSegments()chức năng. ( Tài liệu Android )

Hãy xem xét URI mẫu của bạn:

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

Bạn có thể lấy phân đoạn cuối cùng bằng cách sử dụng:

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

lastSegmentsẽ được id.


1

Bạn cũng có thể sử dụng ReplaceAll:

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

System.out.println(lastSegment);

kết quả:

id

0

Tôi đang sử dụng phần sau trong một lớp tiện ích:

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

Lấy URL từ URI và sử dụng getFile () nếu bạn chưa sẵn sàng sử dụng cách giải nén tệp chuỗi con.


2
sẽ không hoạt động, hãy xem javadoc của getFile (): Lấy tên tệp của URL này. Phần tệp trả về sẽ giống như getPath (), cộng với phần nối giá trị của getQuery (), nếu có. Nếu không có phần truy vấn, phương pháp này và getPath () sẽ trả về kết quả giống hệt nhau).
sfussenegger

getPath()Không sử dụng getFile().
Jason C
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.