Chaîne divisée avec un point comme délimiteur


100

Je me demande si je vais couper une chaîne dans .le bon sens? Mon code est:

String[] fn = filename.split(".");
return fn[0];

Je n'ai besoin que de la première partie de la chaîne, c'est pourquoi je retourne le premier élément. Je demande parce que j'ai remarqué dans l'API que cela .signifie n'importe quel caractère, alors maintenant je suis coincé.

Réponses:


174

split()accepte une expression régulière, vous devez donc échapper .pour ne pas la considérer comme un méta-caractère regex. Voici un exemple:

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

17

Split utilise des expressions régulières, où «.» est un caractère spécial qui signifie n'importe quoi. Vous devez y échapper si vous voulez réellement qu'il corresponde au "." personnage:

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

(un '\' pour échapper au '.' dans l'expression régulière, et l'autre pour échapper au premier dans la chaîne Java)

De plus, je ne suggérerais pas de renvoyer fn [0] car si vous avez un fichier nommé something.blabla.txt, qui est un nom valide, vous ne retournerez pas le nom de fichier réel. Au lieu de cela, je pense que c'est mieux si vous utilisez:

int idx = filename.lastIndexOf('.');
return filename.subString(0, idx);

La question est étiquetée Java, pas Javascript, ce à quoi vous avez lié.
Andrei Fierbinteanu

17

Je ne vois que des solutions ici mais pas d'explication complète du problème, j'ai donc décidé de poster cette réponse

Problème

Vous devez savoir peu de choses sur text.split(delim). splitméthode:

  1. accepte comme argument l'expression régulière (regex) qui décrit le délimiteur sur lequel on veut se diviser,
  2. si delimexiste à la fin de textlike in a,b,c,,(où se trouve le délimiteur ,) splitdans un premier temps créera un tableau comme ["a" "b" "c" "" ""]mais puisque dans la plupart des cas nous n'avons pas vraiment besoin de ces chaînes vides de fin, il les supprime également automatiquement pour nous. Il crée donc un autre tableau sans ces chaînes vides de fin et le renvoie .

Vous devez également savoir que le point. est un caractère spécial dans les regex . Il représente n'importe quel caractère (sauf les séparateurs de ligne mais cela peut être changé avec un Pattern.DOTALLdrapeau).

Donc, pour une chaîne comme "abc"si nous divisions sur la "." splitméthode

  1. créer un tableau comme ["" "" "" ""],
  2. mais comme ce tableau ne contient que des chaînes vides et qu'elles sont toutes à la fin, elles seront supprimées (comme indiqué au deuxième point précédent)

ce qui signifie que nous obtiendrons comme résultat un tableau vide [](sans élément, pas même une chaîne vide), donc nous ne pouvons pas l'utiliser fn[0]car il n'y a pas d'index 0.

Solution

Pour résoudre ce problème, vous devez simplement créer une expression régulière qui représente le point. Pour ce faire, nous devons échapper à cela .. Il y a peu de façons de le faire, mais le plus simple est probablement d'utiliser \(ce qui dans String doit être écrit "\\"car il \est également spécial là-bas et nécessite qu'un autre \soit échappé).

La solution à votre problème peut donc ressembler à

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

Prime

Vous pouvez également utiliser d'autres moyens pour échapper à ce point, comme

  • en utilisant la classe de caractères split("[.]")
  • l'enveloppant dans un devis split("\\Q.\\E")
  • en utilisant une instance de Pattern appropriée avec un Pattern.LITERALdrapeau
  • ou utilisez simplement split(Pattern.quote("."))et laissez regex s'échapper pour vous.

ceci .. J'aime vraiment le: split("[.]")
Dragonborn

15

la méthode String # split (String) utilise des expressions régulières. Dans les expressions régulières, le "." caractère signifie "n'importe quel caractère". Vous pouvez éviter ce comportement en échappant au "."

filename.split("\\.");

ou dire à la méthode de fractionnement de se séparer à une classe de caractères:

filename.split("[.]");

Les classes de caractères sont des collections de caractères. Tu pourrais écrire

filename.split("[-.;ld7]");

et le nom de fichier serait divisé à chaque "-", ".", ";", "l", "d" ou "7". À l'intérieur des classes de caractères, le "." n'est pas un caractère spécial ("métacaractère").


@MisterSmith Vous voudrez peut-être jeter un œil au langage de programmation ici. Nous parlons de java, pas de javascript.
f1sh

Tu as tout à fait raison. J'étais fatigué hier, ayant codé dans les deux langues, n'ayant pas remarqué les types de données Java. Je pensais que les réponses étaient peut-être correctes en 2010, mais d'une manière ou d'une autre, les navigateurs se sont aujourd'hui comportés d'une manière différente.
Mister Smith

7

Comme DOT (.) Est considéré comme un caractère spécial et que la méthode de fractionnement de String attend une expression régulière que vous devez faire comme ceci -

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

En java, les caractères spéciaux doivent être échappés avec un "\" mais comme "\" est également un caractère spécial en Java, vous devez à nouveau l'échapper avec un autre "\"!



2

Ne serait-il pas plus efficace d'utiliser

 filename.substring(0, filename.indexOf("."))

si vous voulez seulement ce qui se passe jusqu'au premier point?


2

Habituellement, ce n'est PAS une bonne idée de le démasquer à la main. Il existe une méthode dans la classe Pattern pour cette tâche:

java.util.regex
static String quote(String s) 


0

Remarque: il faut faire plus attention avec cet extrait de code, même après l'échappement du point!

Si le nom de fichier est juste la chaîne ".", Alors fn finira toujours par avoir une longueur de 0 et fn [0] lancera toujours une exception!

En effet, si le motif correspond au moins une fois, alors split supprimera toutes les chaînes vides de fin (donc aussi celle avant le point!) Du tableau, laissant un tableau vide à retourner.


La solution la plus simple dans des cas comme celui qui nous occupe est de passer également un argument de limite de 2 à l'appel de split: String [] fn = filename.split ("[.]", 2);
avl42

0

La solution qui a fonctionné pour moi est la suivante

filename.split ("[.]");


0

Utiliser ApacheCommons, c'est le plus simple:

File file = ...
FilenameUtils.getBaseName(file.getName());

Notez qu'il extrait également un nom de fichier du chemin complet.


-2

splitprend une expression régulière comme argument. Donc, vous devriez passer "\."au lieu de "."car "."est un métacaractère dans regex.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.