Jak uzyskać ostatni segment ścieżki identyfikatora URI


114

Mam jako dane wejściowe ciąg, który jest URI. jak można uzyskać ostatni segment ścieżki (w moim przypadku jest to identyfikator)?

To jest mój wejściowy adres URL:

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

i muszę uzyskać identyfikator, który próbowałem z tym:

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

ale to nie działa i na pewno musi istnieć lepszy sposób, aby to zrobić.

Odpowiedzi:


174

czy tego szukasz:

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

alternatywnie

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
Szukałem Android.net.Uri (nie java.net.URI) i trafiłem tutaj. Jeśli zamiast tego używasz tego, istnieje metoda o nazwie getLastPathSegment (), która powinna zrobić to samo. :)
pm_labs

5
Po prostu zrób to String idStr = new File(uri.getPath()).getName()samo, co ta odpowiedź, ale używa Filezamiast Stringdo podzielenia ścieżki.
Jason C

to nie zadziała w przypadku adresów URL, takich jak example.com/job/senior-health-and-nutrition-advisor/?param=true . Ostatni „/” sprawia kłopoty. Potrzebujesz czegoś więcej dobrego, odpowiedź getLastPathSegment () udzielona przez @paul_sns jest idealna.
Vaibhav Kadam,

@VaibhavKadam no cóż, technicznie rzecz biorąc, można by argumentować, że ostatni segment to pusty ciąg. Ale jeśli nie tego chcesz, po prostu użyj:while (path.endsWith("/")) path = path.substring(0, path.length() - 1);
sfussenegger

@sfussenegger Moja wina, że ​​nie czytałem tagów, o których mowa. Myślałem, że ma tag androida. Cóż, +1 dla android.net.uri. :). Android przejmuje 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
Czy to jest „android.net.Uri”? Baza zawiera tagi pytania, zakładany byłby java.net.URI i nie ma getLastPathSegment () ...
Michael Geiser

Ponadto Urinazwa klasy systemu Android jest zapisana małymi literami i nie można jej utworzyć. Poprawiłem twoją odpowiedź, aby użyć statycznej metody fabryki Uri.parse().
cicha mięta

GetLastPathSegment nie istnieje tutaj.
Abdullah Shoaib

2
ma getLastPathSegment (), ale nie działa! zwraca null!
Junia Montana

Wygląda na to, że getLastPathSegment () losowo wypluwa mi pełną ścieżkę.
MobDev

48

Oto krótka metoda:

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

Kod testu:

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

Wynik:

42
Foo
Bar

Wyjaśnienie:

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

chociaż jestem wielkim fanem wyrażeń regularnych i sam często ich używam, zdaję sobie sprawę, że dla większości programistów regex jest tak samo tępy, jak to tylko możliwe. nie jest prostsze w tym, że nie jest szybko zrozumiane.
Bill Turner,

/W zanegowanej klasy postaci [^/?]nie jest konieczne, ponieważ nigdy nie zostaną dopasowane. .*/zawsze będzie pasować do ostatniej / w ciągu, więc nie /należy napotkać żadnego innego .
Stefan van den Akker

nie działa dla tego rodzaju linków. http://example.com/foo#reply2Byłoby wspaniale, gdybyś mógł zaktualizować swoją odpowiedź, aby go rozwiązać. Dzięki
Seth

23

Wiem, że to stare, ale tutaj rozwiązania wydają się dość rozwlekłe. Po prostu łatwo czytelny, jednoliniowy, jeśli masz URLlub URI:

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

Lub jeśli masz String:

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

Czy to działa ze wszystkimi możliwymi opcjami adresu URL, takimi jak a.co/last?a=1#frag. Nie sądzę, ponieważ kod ma podciąg ostatniego symbolu ścieżki aż do końca: path.substring(index + 1).
AlikElzin-kilaka

4
@alik Pytanie dotyczy ostatniego segmentu ścieżki. Zapytanie i fragment nie są częścią segmentu ścieżki.
Jason C

13

Jeśli używasz języka Java 8 i chcesz, aby ostatni segment w ścieżce do pliku mógł to zrobić.

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

Jeśli masz taki adres URL, jak http://base_path/some_segment/idmożesz to zrobić.

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

4
Ryzykowne, ponieważ java.nio.file.Paths # get zależy od systemu plików, na którym działa maszyna JVM. Nie ma gwarancji, że rozpozna identyfikator URI z ukośnikami jako separatorami ścieżek.
Adrian Baker

2
A co z identyfikatorem URI z parametrami zapytania? Traktowanie losowego identyfikatora URI jako ścieżki systemu plików wymaga podania wyjątku.
Abhijit Sarkar

9

W systemie Android

Android ma wbudowaną klasę do zarządzania identyfikatorami URI.

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

Czasami po prostu wypluwa pełną ścieżkę. Nie wiem, dlaczego i kiedy wydaje się to przypadkowe.
MobDev

Jeśli uda ci się złapać zawartość, którą analizuje, być może możesz skonfigurować test jednostkowy, aby się upewnić.
Brill Pappin

8

W Javie 7+ można połączyć kilka poprzednich odpowiedzi, aby umożliwić pobranie dowolnego segmentu ścieżki z identyfikatora URI, a nie tylko ostatniego segmentu. Możemy przekonwertować URI na java.nio.file.Pathobiekt, aby skorzystać z jego getName(int)metody.

Niestety, statyczna fabryka Paths.get(uri)nie jest zbudowana do obsługi schematu http, więc najpierw musimy oddzielić schemat od ścieżki 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();

Aby uzyskać ostatni segment w jednym wierszu kodu, po prostu zagnieżdżaj wiersze powyżej.

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

Aby uzyskać przedostatni segment, unikając numerów indeksów i potencjalnych błędów poza jednym, użyj getParent()metody.

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

Zauważ, że getParent()metodę można wywoływać wielokrotnie, aby pobrać segmenty w odwrotnej kolejności. W tym przykładzie ścieżka zawiera tylko dwa segmenty, w przeciwnym razie wywołanie getParent().getParent()spowoduje pobranie trzeciego do ostatniego segmentu.


6

Jeśli commons-iowłączyłeś do swojego projektu, możesz to zrobić bez tworzenia zbędnych obiektów za pomocąorg.apache.commons.io.FilenameUtils

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

Da ci ostatnią część ścieżki, czyli id


3

Możesz użyć getPathSegments()funkcji. ( Dokumentacja systemu Android )

Rozważ przykładowy identyfikator URI:

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

Możesz uzyskać ostatni segment za pomocą:

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

lastSegmentbędzie id.


1

Możesz także użyć replaceAll:

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

System.out.println(lastSegment);

wynik:

id

0

Używam następujących w klasie użytkowej:

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

Pobierz adres URL z URI i użyj getFile (), jeśli nie jesteś gotowy na użycie podciągowego sposobu wypakowywania pliku.


2
nie zadziała, zobacz javadoc funkcji getFile (): Pobiera nazwę pliku z tego adresu URL. Zwrócona część pliku będzie taka sama jak getPath (), plus konkatenacja wartości getQuery (), jeśli taka istnieje. Jeśli nie ma części zapytania, ta metoda i getPath () zwrócą identyczne wyniki.)
sfussenegger

getPath()Nie używaj getFile().
Jason C
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.