Come ottenere l'ultimo segmento di percorso di un URI


114

Ho come input una stringa che è un file URI. come è possibile ottenere l'ultimo segmento di percorso (che nel mio caso è un id)?

Questo è il mio URL di input:

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

e devo ottenere l'id che ho provato con questo:

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

ma non funziona, e sicuramente ci deve essere un modo migliore per farlo.

Risposte:


174

è quello che stai cercando:

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

in alternativa

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
Stavo cercando android.net.Uri (non java.net.URI) di Android e sono finito qui. Se invece lo stai usando, c'è un metodo chiamato getLastPathSegment () che dovrebbe fare la stessa cosa. :)
pm_labs

5
Basta fare String idStr = new File(uri.getPath()).getName(), come questa risposta, ma usa Fileinvece di Stringdividere il percorso.
Jason C

questo non funzionerà per URL come example.com/job/senior-health-and-nutrition-advisor/?param=true . L'ultima "/" sta creando problemi. Hai bisogno di qualcosa di più buono getLastPathSegment () La risposta data da @paul_sns è perfetta.
Vaibhav Kadam

@VaibhavKadam beh, tecnicamente potresti sostenere che l'ultimo segmento è una stringa vuota. Ma se non è quello che vuoi usa semplicemente:while (path.endsWith("/")) path = path.substring(0, path.length() - 1);
sfussenegger

@sfussenegger Colpa mia, non ho letto i TAG in questione. Pensavo avesse il tag di Android. Bene +1 per android.net.uri. :). Android sta prendendo il sopravvento su 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
Questo è "android.net.Uri"? Base don i tag della domanda, si presume java.net.URI e non ha un getLastPathSegment () ...
Michael Geiser

Inoltre, il Urinome della classe Android è minuscolo e non può essere istanziato. Ho corretto la tua risposta per utilizzare il metodo di fabbrica statico Uri.parse().
quietmint

GetLastPathSegment non esiste qui.
Abdullah Shoaib

2
ha getLastPathSegment () ma non funziona! restituisce null!
Junia Montana

Sembra che getLastPathSegment () sputi casualmente il percorso completo per me.
MobDev

48

Ecco un breve metodo per farlo:

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

Codice di prova:

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

Produzione:

42
foo
bar

Spiegazione:

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

Sebbene io sia un grande fan di regex e lo uso spesso io stesso, riconosco che per la maggior parte degli sviluppatori, regex è quasi ottuso come diventa. non è più semplice nel fatto che non si capisce rapidamente.
Bill Turner

La /classe di caratteri negata [^/?]non è necessaria, perché non verrà mai trovata. .*/corrisponderà sempre all'ultimo / nella stringa, quindi nessun altro /dovrebbe essere incontrato.
Stefan van den Akker

non funziona per questo tipo di collegamento http://example.com/foo#reply2, sarebbe fantastico se potessi aggiornare la tua risposta per risolverlo. Grazie
Seth

23

So che questo è vecchio, ma le soluzioni qui sembrano piuttosto prolisse. Solo un one-liner facilmente leggibile se hai un URLo URI:

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

O se hai un String:

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

Funziona con tutte le possibili opzioni di un URL, come a.co/last?a=1#frag. Non credo, come il codice non sottostringa dell'ultimo simbolo sentiero fino alla fine: path.substring(index + 1).
AlikElzin-kilaka

4
@alik La domanda richiede l'ultimo segmento di percorso. La query e il frammento non fanno parte del segmento di percorso.
Jason C

13

Se stai usando Java 8 e vuoi l'ultimo segmento in un percorso di file puoi farlo.

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

Se hai un URL come http://base_path/some_segment/idpuoi fare.

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

4
Rischioso perché java.nio.file.Paths # get dipende dal filesystem del sistema operativo su cui è in esecuzione JVM. Non c'è alcuna garanzia che riconoscerà un URI con barre in avanti come separatori di percorso.
Adrian Baker

2
E l'URI con i parametri della query? Trattare un URI casuale come un percorso del file system richiede un'eccezione.
Abhijit Sarkar

9

In Android

Android ha una classe incorporata per la gestione degli URI.

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

A volte questo sputa solo il percorso completo. Non so perché o quando sembra essere casuale.
MobDev

Se riesci a catturare il contenuto che sta analizzando, forse puoi impostare uno unit test per assicurartene.
Brill Pappin

8

In Java 7+ alcune delle risposte precedenti possono essere combinate per consentire il recupero di qualsiasi segmento di percorso da un URI, piuttosto che solo l'ultimo segmento. Possiamo convertire l'URI in un java.nio.file.Pathoggetto, per sfruttare il suo getName(int)metodo.

Sfortunatamente, la factory statica Paths.get(uri)non è costruita per gestire lo schema http, quindi dobbiamo prima separare lo schema dal percorso dell'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();

Per ottenere l'ultimo segmento in una riga di codice, annidare semplicemente le righe sopra.

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

Per ottenere il penultimo segmento evitando i numeri di indice e la possibilità di errori off-by-one, utilizzare il getParent()metodo.

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

Nota che il getParent()metodo può essere chiamato ripetutamente per recuperare i segmenti in ordine inverso. In questo esempio, il percorso contiene solo due segmenti, altrimenti la chiamata getParent().getParent()recupererebbe il terzultimo segmento.


6

Se hai commons-ioincluso nel tuo progetto, puoi farlo senza creare oggetti non necessari conorg.apache.commons.io.FilenameUtils

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

Ti darà l'ultima parte del percorso, che è il file id


3

Puoi usare getPathSegments()function. ( Documentazione Android )

Considera l'URI di esempio:

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

Puoi ottenere l'ultimo segmento utilizzando:

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

lastSegmentsarà id.


1

Puoi anche usare replaceAll:

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

System.out.println(lastSegment);

risultato:

id

0

Sto usando quanto segue in una classe di utilità:

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

Ottieni l'URL dall'URI e usa getFile () se non sei pronto per usare la sottostringa per estrarre il file.


2
non funzionerà, vedere javadoc di getFile (): Ottiene il nome del file di questo URL. La parte del file restituita sarà la stessa di getPath (), più la concatenazione del valore di getQuery (), se presente. Se non è presente una porzione di query, questo metodo e getPath () restituiranno risultati identici.)
sfussenegger,

getPath()Non usare getFile().
Jason C
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.