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

하지만 작동하지 않습니다. 확실히 더 나은 방법이 있어야합니다.

답변:


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.net.Uri (java.net.URI가 아님)를 찾고 있었고 여기서 끝났습니다. 대신 사용하는 경우 동일한 작업을 수행해야하는 getLastPathSegment ()라는 메서드가 있습니다. :)
pm_labs 2013 년

5
그냥 할 String idStr = new File(uri.getPath()).getName()이 대답과 동일하지만, 사용하는 File대신 String경로를 분할 할 수 있습니다.
Jason C

example.com/job/senior-health-and-nutrition-advisor/?param=true 와 같은 URL에서는 작동하지 않습니다 . 마지막 "/"가 문제를 일으키고 있습니다. 더 좋은 것이 필요합니다 @paul_sns가 제공하는 getLastPathSegment () 대답은 완벽합니다.
Vaibhav Kadam

@VaibhavKadam 음, 기술적으로 마지막 세그먼트는 빈 문자열이라고 주장 할 수 있습니다. 그게 아니라면하지만 당신은 단순히 사용 싶은 :while (path.endsWith("/")) path = path.substring(0, path.length() - 1);
sfussenegger

@sfussenegger 문제의 TAG를 읽지 않았습니다. 나는 그것이 안드로이드의 태그가 있다고 생각했다. android.net.uri는 +1입니다. :). 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을 (없는 질문의 태그를 돈
마이클 GEISER에게

또한 Android Uri클래스 이름은 소문자이며 인스턴스화 할 수 없습니다. 정적 공장 방법을 사용하도록 답변을 수정했습니다 Uri.parse().
quietmint

GetLastPathSegment가 여기에 없습니다.
Abdullah Shoaib

2
getLastPathSegment ()가 있지만 작동하지 않습니다! null을 반환합니다!
Junia Montana

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

설명:

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

나는 정규식의 열렬한 팬이며 자주 사용하지만 대부분의 개발자에게 정규식은 점점 둔감하다는 것을 알고 있습니다. 그것은 빨리 이해되지 않는다는 사실에서 더 간단하지 않습니다.
Bill Turner

/부정 된 문자 클래스는 [^/?]이 일치하지 않을 것이기 때문에, 불필요합니다. .*/항상 문자열의 마지막 항목과 일치 /하므로 다른 항목 /을 만나서는 안됩니다.
Stefan van den Akker

이런 종류의 링크 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 질문은 마지막 경로 세그먼트를 묻습니다. 쿼리와 조각은 경로 세그먼트의 일부가 아닙니다.
Jason C

13

Java 8을 사용 중이고 파일 경로의 마지막 세그먼트를 원하는 경우 수행 할 수 있습니다.

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

당신이 http://base_path/some_segment/id할 수있는 것과 같은 URL이 있다면 .

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를 인식한다는 보장은 없습니다.
Adrian Baker

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에서 모든 경로 세그먼트를 검색 할 수 있습니다 . 메서드를 java.nio.file.Path활용하기 위해 URI를 객체 로 변환 할 수 있습니다 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입니다.


1

replaceAll을 사용할 수도 있습니다.

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

System.out.println(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

getPath()not을 사용하십시오 getFile().
Jason C
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.