467 votes

Chaîne de caractères Java séparée par "." (point)

Pourquoi la deuxième ligne de ce code jette ArrayIndexOutOfBoundsException ?

String filename = "D:/some folder/001.docx";
String extensionRemoved = filename.split(".")[0];

Pendant que ça marche :

String driveLetter = filename.split("/")[0];

J'utilise Java 7.

7 votes

Split n'utilise pas une chaîne regex ? Dans ce cas, "." signifie n'importe quel caractère.

4 votes

...et c'est un DOUBLE backslash pour délimiter.

926voto

Bohemian Points 134107

Vous devez échapper le point si vous voulez diviser sur un littéral point :

String extensionRemoved = filename.split("\\.")[0];

Sinon, vous divisez sur la regex. . ce qui signifie "tout caractère".
Notez la double barre oblique inversée nécessaire pour créer une simple barre oblique inversée dans la regex.


Vous obtenez un ArrayIndexOutOfBoundsException parce que votre chaîne d'entrée est juste un point, c'est-à-dire "." qui est un cas limite qui produit un tableau vide lorsqu'il est divisé sur le point ; split(regex) supprime tous les blancs de fin de tableau du résultat, mais comme la division d'un point sur un point ne laisse que deux blancs, une fois les blancs de fin de tableau supprimés, on se retrouve avec un tableau vide.

Pour éviter de recevoir un ArrayIndexOutOfBoundsException pour ce cas limite, utilisez la version surchargée de l'option split(regex, limit) qui a un second paramètre qui est la taille limite du tableau résultant. Lorsque limit es négatif le comportement consistant à supprimer les blancs de fin de tableau est désactivé :

".".split("\\.", -1) // returns an array of two blanks, ie ["", ""]

c'est-à-dire, lorsque filename est juste un point "." en appelant filename.split("\\.", -1)[0] retournera un blanc, mais appeler filename.split("\\.")[0] lancera un ArrayIndexOutOfBoundsException .

1 votes

Notez que le nom de fichier peut contenir plusieurs points. Il faut utiliser le dernier indice de "." et l'utiliser pour trouver la sous-chaîne du nom de fichier.

2 votes

@saurabheights La question ne portait pas sur une regex correcte, mais plutôt sur la raison pour laquelle il y avait une erreur. ArrayIndexOutOfBoundsException . Cela dit, vous avez tort : il n'est pas nécessaire de savoir où se trouve le dernier point ; il suffit d'utiliser la bonne expression rationnelle : filename.split("\\.(?=[^.]*$)") . Ce dernier utilise un regarder devant soi pour affirmer qu'il n'y a aucun point dans l'entrée qui suit le point correspondant.

1 votes

@emma vous pouvez les supprimer vous-même via le lien "supprimer" juste en dessous de la question.

132voto

aimhaj Points 32

Le point "." est un caractère spécial dans le moteur Regex de Java, vous devez donc utiliser ". \\. "pour échapper à ce caractère :

final String extensionRemoved = filename.split("\\.")[0];

J'espère que cela vous aidera

27 votes

Il est no un caractère spécial en Java. C'est un caractère spécial dans le moteur regex de Java.

1 votes

Je n'ai pas été très précis dans ma réponse mais je suis d'accord avec vous. merci pour la précision ;)

1 votes

C'est une distinction qui vaut la peine d'être faite. De plus, je viens de réaliser que je me suis un peu trompé moi-même ; c'est un caractère spécial en Java, mais ce n'est pas pour cela qu'il pose un problème ici. Quoi qu'il en soit.

35voto

Gabriele Mariotti Points 7243

Cela s'explique par le fait que . est un caractère réservé dans une expression régulière, représentant n'importe quel caractère. Au lieu de cela, nous devrions utiliser l'instruction suivante :

String extensionRemoved = filename.split("\\.")[0];

20voto

Ivaylo Strandjev Points 38924

Je crois que vous devriez échapper au point. Essayez :

String filename = "D:/some folder/001.docx";
String extensionRemoved = filename.split("\\.")[0];

Sinon, point est interprété comme n'importe quel caractère dans les expressions régulières.

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