So erhalten Sie das letzte Pfadsegment eines URI

114

Ich habe als Eingabe eine Zeichenfolge, die a ist URI. Wie ist es möglich, das letzte Pfadsegment zu erhalten (das in meinem Fall eine ID ist)?

Dies ist meine Eingabe-URL:

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

und ich muss die ID erhalten, die ich damit versucht habe:

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

aber es funktioniert nicht und es muss sicherlich einen besseren Weg geben, es zu tun.

DX89B
quelle

Antworten:

174

ist das, wonach Sie suchen:

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

Alternative

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);
sfussenegger
quelle
49
Ich habe nach Android's android.net.Uri (nicht java.net.URI) gesucht und bin hier gelandet. Wenn Sie das stattdessen verwenden, gibt es dort eine Methode namens getLastPathSegment (), die dasselbe tun sollte. :)
pm_labs
5
Tun Sie String idStr = new File(uri.getPath()).getName()dies einfach wie in dieser Antwort, verwenden Sie jedoch Filestatt String, um den Pfad zu teilen.
Jason C
Dies funktioniert nicht für URLs wie example.com/job/senior-health-and-nutrition-advisor/?param=true . Das letzte "/" macht Ärger. Benötigen Sie etwas mehr gute getLastPathSegment () Antwort von @paul_sns ist perfekt.
Vaibhav Kadam
@ VaibhavKadam Nun, technisch könnte man argumentieren, dass das letzte Segment eine leere Zeichenfolge ist. Aber wenn das nicht das ist, was Sie wollen, verwenden Sie einfach:while (path.endsWith("/")) path = path.substring(0, path.length() - 1);
sfussenegger
@sfussenegger Mein schlechtes Ich habe die fraglichen TAGs nicht gelesen. Ich dachte, es hat Tag von Android. Nun +1 für android.net.uri. :). Android übernimmt JAVA.
Vaibhav Kadam
69
import android.net.Uri;
Uri uri = Uri.parse("http://example.com/foo/bar/42?param=true");
String token = uri.getLastPathSegment();
Colateral
quelle
1
Ist das "android.net.Uri"? Basis Don die Tags der Frage, java.net.URI würde angenommen und es hat kein getLastPathSegment () ...
Michael Geiser
Außerdem ist der UriName der Android- Klasse klein geschrieben und kann nicht instanziiert werden. Ich habe Ihre Antwort korrigiert, um die statische Factory-Methode zu verwenden Uri.parse().
quietmint
GetLastPathSegment existiert hier nicht.
Abdullah Shoaib
2
es hat getLastPathSegment (), aber es funktioniert nicht! gibt null zurück!
Junia Montana
Scheint, als würde getLastPathSegment () zufällig den vollständigen Pfad für mich ausspucken.
MobDev
48

Hier ist eine kurze Methode, um dies zu tun:

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

Testcode:

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

Ausgabe:

42
foo
bar

Erläuterung:

.*/      // 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
Sean Patrick Floyd
quelle
Obwohl ich ein großer Fan von Regex bin und es häufig selbst benutze, erkenne ich, dass Regex für die meisten Entwickler so stumpf ist, wie es nur geht. es ist nicht einfacher, weil es nicht schnell verstanden wird.
Bill Turner
Die /in der negierten Zeichenklasse [^/?]ist nicht erforderlich, da sie niemals übereinstimmt. .*/wird immer mit dem letzten / in der Zeichenfolge übereinstimmen , daher sollte keine andere /angetroffen werden.
Stefan van den Akker
funktioniert nicht für diese Art von Link http://example.com/foo#reply2. Es wäre großartig, wenn Sie Ihre Antwort aktualisieren könnten, um sie zu lösen. Danke
Seth
23

Ich weiß, dass dies alt ist, aber die Lösungen hier scheinen ziemlich ausführlich zu sein. Nur ein leicht lesbarer Einzeiler, wenn Sie einen URLoder haben URI:

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

Oder wenn Sie eine haben String:

String filename = new File(new URL(url).getPath()).getName();
Jason C.
quelle
Funktioniert es mit allen möglichen Optionen einer URL, wie a.co/last?a=1#frag. Ich denke nicht, da der Code die Teilzeichenfolge des letzten Pfadsymbols bis zum Ende ausführt : path.substring(index + 1).
AlikElzin-Kilaka
4
@alik Die Frage fragt nach dem letzten Pfadsegment. Die Abfrage und das Fragment sind nicht Teil des Pfadsegments.
Jason C
13

Wenn Sie Java 8 verwenden und das letzte Segment in einem Dateipfad möchten, können Sie dies tun.

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

Wenn Sie eine URL haben, wie http://base_path/some_segment/idSie es tun können.

final Path urlPath = Paths.get("http://base_path/some_segment/id");
final Path lastSegment = urlPath.getName(urlPath.getNameCount() - 1);
Will Humphreys
quelle
4
Riskant, da java.nio.file.Paths # get vom Betriebssystem-Dateisystem abhängt, auf dem die JVM ausgeführt wird. Es gibt keine Garantie dafür, dass ein URI mit Schrägstrichen als Pfadtrennzeichen erkannt wird.
Adrian Baker
2
Was ist mit URI mit Abfrageparametern? Wenn Sie einen zufälligen URI als Dateisystempfad behandeln, wird eine Ausnahme angefordert.
Abhijit Sarkar
8

In Android

Android verfügt über eine integrierte Klasse zum Verwalten von URIs.

Uri uri = Uri.parse("http://base_path/some_segment/id");
String lastPathSegment = uri.getLastPathSegment()
Brill Pappin
quelle
Manchmal spuckt dies nur den vollen Weg aus. Ich bin mir nicht sicher, warum oder wann es zufällig zu sein scheint.
MobDev
Wenn Sie den zu analysierenden Inhalt abfangen können, können Sie möglicherweise einen Komponententest einrichten, um dies sicherzustellen.
Brill Pappin
7

In Java 7+ können einige der vorherigen Antworten kombiniert werden, um das Abrufen eines beliebigen Pfadsegments aus einem URI und nicht nur des letzten Segments zu ermöglichen. Wir können den URI in ein java.nio.file.PathObjekt konvertieren , um seine getName(int)Methode zu nutzen.

Leider ist die statische Factory Paths.get(uri)nicht für das http-Schema ausgelegt, daher müssen wir zuerst das Schema vom Pfad der URI trennen.

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

Um das letzte Segment in einer Codezeile zu erhalten, verschachteln Sie einfach die obigen Zeilen.

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

Verwenden Sie die getParent()Methode , um das vorletzte Segment zu erhalten und dabei Indexnummern und mögliche Fehler zu vermeiden .

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

Beachten Sie, dass die getParent()Methode wiederholt aufgerufen werden kann, um Segmente in umgekehrter Reihenfolge abzurufen. In diesem Beispiel enthält der Pfad nur zwei Segmente, andernfalls getParent().getParent()würde der Aufruf das vorletzte Segment abrufen.

jaco0646
quelle
5

Wenn Sie commons-ioin Ihr Projekt aufgenommen haben, können Sie dies tun, ohne unnötige Objekte mit zu erstellenorg.apache.commons.io.FilenameUtils

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

Wird Ihnen den letzten Teil des Pfades geben, nämlich den id

Bnrdo
quelle
3

Sie können die getPathSegments()Funktion verwenden. ( Android-Dokumentation )

Betrachten Sie Ihre Beispiel-URI:

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

Sie können das letzte Segment erhalten mit:

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

lastSegmentwird sein id.

Sina Masnadi
quelle
1

Sie können auch replaceAll verwenden:

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

System.out.println(lastSegment);

Ergebnis:

id
Krzysztof Cichocki
quelle
0

Ich verwende Folgendes in einer Utility-Klasse:

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();
}
Gerold Broser
quelle
-1

Rufen Sie die URL vom URI ab und verwenden Sie getFile (), wenn Sie nicht bereit sind, die Teilzeichenfolge zum Extrahieren von Dateien zu verwenden.

Nageswara Rao
quelle
2
funktioniert nicht, siehe javadoc von getFile (): Ruft den Dateinamen dieser URL ab. Der zurückgegebene Dateiteil entspricht getPath () zuzüglich der Verkettung des Werts von getQuery (), falls vorhanden. Wenn es keinen Abfrageteil gibt, geben diese Methode und getPath () identische Ergebnisse zurück.)
sfussenegger
Verwenden Sie getPath()nicht getFile().
Jason C