web-dev-qa-db-fra.com

Java String split supprimé des valeurs vides

J'essaie de diviser la valeur à l'aide d'un séparateur . Mais je trouve des résultats surprenants

String data = "5|6|7||8|9||";
String[] split = data.split("\\|");
System.out.println(split.length);

Je m'attends à obtenir 8 valeurs. [5,6,7, VIDE, 8,9, VIDE, VIDE] Mais je n'obtiens que 6 valeurs.

Toute idée et comment y remédier. Peu importe que la valeur EMPTY vienne n'importe où, elle devrait être en tableau.

222
Reddy

split(delimiter) par défaut supprime les chaînes vides de fin du tableau de résultats. Pour désactiver ce mécanisme, nous devons utiliser la version surchargée de split(delimiter, limit) avec limit défini sur une valeur négative telle que

String[] split = data.split("\\|", -1);

Petit plus de détails:
split(regex) renvoie en interne le résultat de split(regex, 0) et dans documentation de cette méthode, vous pouvez trouver (c'est moi qui souligne)

Le paramètre limit contrôle le nombre d'applications du modèle et affecte donc la longueur du tableau résultant. 

Si la limite n est supérieure à zéro alors le modèle sera appliqué au plus n - 1 fois, la longueur du tableau ne sera pas supérieure à n et la dernière entrée du tableau contiendra toutes les entrées au-delà de la dernière correspondance. délimiteur. 

Si n est non-positif, le motif sera appliqué autant de fois que possible et le tableau pourra avoir n'importe quelle longueur. 

Si n est zero, le motif sera appliqué autant de fois que possible, le tableau peut avoir n'importe quelle longueur et trailing les chaînes vides seront ignorées.

Exception:

Il est à noter que la suppression de la chaîne de fin vide est logique uniquement si de telles chaînes vides sont créées par un mécanisme de division. Donc pour "".split(anything) puisque nous ne pouvons pas séparer "" plus loin, nous aurons comme résultat le tableau [""].
Cela se produit parce que la division n'a pas eu lieu ici, donc "" malgré le fait qu'il soit vide et que la fin représente la chaîne originale, et non la chaîne vide qui était créée en fractionnant le processus.

390
jlordo

De la documentation de String.split(String regex) :

Cette méthode fonctionne comme si elle invoquait la méthode de scission à deux arguments avec l'expression donnée et un argument limit égal à zéro. Les chaînes vides de fin ne sont donc pas incluses dans le tableau résultant. 

Vous devrez donc utiliser la version à deux arguments String.split(String regex, int limit) avec une valeur négative:

String[] split = data.split("\\|",-1);

Doc:

Si la limite n est supérieure à zéro, le motif sera appliqué au plus n fois - 1 fois, la longueur du tableau ne sera pas supérieure à n et la dernière entrée du tableau contiendra toutes les entrées autres que le dernier séparateur mis en correspondance. Si n n'est pas positif, le motif sera appliqué autant de fois que possible et le tableau peut avoir n'importe quelle longueur. Si n est égal à zéro, le modèle sera appliqué autant de fois que possible, le tableau peut avoir n'importe quelle longueur et les chaînes vides de fin seront ignorées.

Cela ne laissera aucun élément vide, y compris le dernier.

31
ppeterka

De String.split () API Doc :

Fractifie cette chaîne autour des correspondances de l'expression régulière donnée . Cette méthode fonctionne comme si elle appelait la méthode de division en deux arguments avec l'expression donnée et un argument limite de zéro. Trailing vide les chaînes ne sont donc pas incluses dans le tableau résultant.

Overloaded String.split (regex, int) convient mieux à votre cas.

4
PermGenError

Une autre option consiste à utiliser le séparateur de goyave. Il n'a pas la surcharge d'une expression régulière (ce dont vous n'avez pas besoin dans ce cas) et par défaut, ne supprime pas les chaînes de fin vides. 

Par exemple:

 String data = "5|6|7||8|9||";
 Iterable<String> results = Splitter.on('|').split(data);
 // convert to array
 String[] asArray = Iterables.toArray(results, String.class);

Pour plus d'informations, consultez le wiki: https://github.com/google/guava/wiki/StringsExplained

3
nickool

vous pouvez avoir plusieurs séparateurs, y compris des espaces, des virgules, des points-virgules, etc. Prenez ceux du groupe répétable avec [] +, comme:

 String[] tokens = "a , b,  ,c; ;d,      ".split( "[,; \t\n\r]+" );

vous aurez 4 jetons - a, b, c, d

les séparateurs de début dans la chaîne source doivent être supprimés avant d'appliquer cette division.

comme réponse à la question posée:

String data = "5|6|7||8|9||";
String[] split = data.split("[\\| \t\n\r]+");

espaces blancs ajoutés au cas où vous auriez ceux-ci comme séparateurs avec |

1
Dmitriy Pichugin