123 votes

Comment obtenir le dernier segment de chemin d'accès d'un URI ?

J'ai comme entrée une chaîne de caractères qui est un URI . comment est-il possible d'obtenir le dernier segment du chemin (qui dans mon cas est un id) ?

Voici mon URL d'entrée :

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

et je dois obtenir l'identifiant que j'ai essayé avec ceci :

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

mais ça ne marche pas, et il doit sûrement y avoir un meilleur moyen de le faire.

0 votes

La méthode getLastPathSegment ne fonctionne pas avec : dans Android 6.0

195voto

sfussenegger Points 16204

C'est ce que vous recherchez :

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

ou encore

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

52 votes

Je cherchais Android.net.Uri (et non java.net.URI) et j'ai atterri ici. Si vous l'utilisez à la place, il y a une méthode appelée getLastPathSegment() qui devrait faire la même chose :)

5 votes

Fais-le. String idStr = new File(uri.getPath()).getName() Identique à cette réponse mais utilise File au lieu de String pour diviser le chemin.

0 votes

Cela ne fonctionnera pas pour les urls comme exemple.com/job/senior-health-and-nutrition-advisor/?param=true . Le dernier "/" pose problème. Besoin de quelque chose de plus bon getLastPathSegment() la réponse donnée par @paul_sns est parfaite.

74voto

Colateral Points 1517
import android.net.Uri;
Uri uri = Uri.parse("http://example.com/foo/bar/42?param=true");
String token = uri.getLastPathSegment();

1 votes

Est-ce "Android.net.Uri" ? D'après les balises de la question, java.net.URI serait supposé et il n'y a pas de getLastPathSegment()...

0 votes

De plus, l'Android Uri le nom de la classe est en minuscule et ne peut pas être instancié. J'ai corrigé votre réponse pour utiliser la méthode de fabrique statique Uri.parse() .

0 votes

GetLastPathSegment n'existe pas ici.

54voto

Sean Patrick Floyd Points 109428

Voici une courte méthode pour le faire :

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

Code de test :

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

Sortie :

42
foo
bar

Explication :

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

0 votes

Bien que je sois un grand fan de la regex et que je l'utilise fréquemment moi-même, je reconnais que pour la plupart des développeurs, la regex est à peu près aussi obtuse que possible. elle n'est pas plus simple dans le sens où elle n'est pas rapidement comprise.

0 votes

Le site / dans la classe de caractères négationnés [^/?] n'est pas nécessaire, car il n'y aura jamais de correspondance. .*/ correspondra toujours à la dernier / dans la chaîne, donc aucun autre / devrait être rencontrée.

1 votes

Ne fonctionne pas pour ce type de lien http://example.com/foo#reply2 Ce serait formidable si vous pouviez mettre à jour votre réponse pour résoudre ce problème. Merci

26voto

Jason C Points 14927

Je sais que c'est vieux, mais les solutions proposées ici semblent plutôt verbeuses. Il s'agit simplement d'une solution facile à lire si vous avez une URL ou URI :

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

Ou si vous avez un String :

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

0 votes

Est-ce que cela fonctionne avec toutes les options possibles d'une URL, par exemple a.co/last?a=1#frag . Je ne pense pas, car le code fait la sous-chaîne du dernier symbole de chemin jusqu'à la fin : path.substring(index + 1) .

4 votes

@alik La question demande le dernier segment de chemin. La requête et le fragment ne font pas partie du segment de chemin.

15voto

Will Humphreys Points 1328

Si vous utilisez Java 8 et que vous voulez le dernier segment dans un chemin de fichier, vous pouvez le faire.

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

Si vous avez une url telle que http://base_path/some_segment/id vous pouvez faire.

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

8 votes

Risqué car java.nio.file.Paths#get dépend du système de fichiers du système d'exploitation sur lequel tourne la JVM. Il n'y a aucune garantie qu'il reconnaîtra un URI avec des barres obliques comme séparateurs de chemin.

2 votes

Qu'en est-il des URI avec des paramètres d'interrogation ? Traiter un URI aléatoire comme un chemin d'accès au système de fichiers revient à demander une exception.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X