2010-04-28 4 views
5

Je dois pouvoir séparer une chaîne d'entrée par des virgules, des points-virgules ou des espaces blancs (ou un mélange des trois). Je voudrais aussi traiter plusieurs délimiteurs consécutifs dans l'entrée comme un seul délimiteur. Voici ce que j'ai jusqu'à présent:String.split() - chaîne principale vide correspondant avant le premier délimiteur?

String regex = "[,;\\s]+";  
return input.split(regex); 

Cela fonctionne, sauf quand la chaîne d'entrée commence par l'un des caractères délimiteurs, auquel cas le premier élément du tableau de résultat est une chaîne vide. Je ne veux pas que mon résultat ait des chaînes vides, de sorte que quelque chose comme, ",,,, ZERO ;,; ONE, TWO ;," renvoie juste un tableau à trois éléments contenant les chaînes capitalisées.

Existe-t-il une meilleure façon de faire cela que de supprimer les caractères principaux qui correspondent à mon reg-ex avant d'appeler String.split?

Merci d'avance!

+0

Pas de réponse en tant que je ne me souviens pas de l'API regex Java, mais vous pouvez simplement rechercher des chaînes de non-délimiteurs au lieu de diviser sur les délimiteurs, par exemple en utilisant une regex comme '[^,; \ s] +'. –

+0

Question apparemment identique, plus récente mais avec une meilleure réponse acceptée: https://stackoverflow.com/questions/9389503/how-to-prevent-java-lang-string-split-from-creating-a-leading-empty-string –

Répondre

3

Si par "mieux" vous voulez dire plus de performance alors vous pouvez essayer de créer une expression régulière qui correspond à ce que vous voulez faire correspondre et d'utiliser Matcher.find dans une boucle et de retirer les correspondances que vous les trouvez. Cela évite de modifier la chaîne en premier. Mais mesurez-le vous-même pour voir lequel est le plus rapide pour vos données. Si par "mieux" vous voulez dire plus simple, alors non je ne pense pas qu'il y ait un moyen plus simple que ce que vous avez suggéré: enlever les séparateurs principaux avant d'appliquer la séparation.

6

Non, il n'y en a pas. Vous ne pouvez pas ignorer arrière délimiteurs en fournissant 0 comme second paramètre méthode split String():

return input.split(regex, 0); 

mais pour mener délimiteurs, vous devrez les première bande:

return input.replaceFirst("^"+regex, "").split(regex, 0); 
+0

Un paramètre négatif? 'Si n vaut zéro alors le motif sera appliqué autant de fois que possible, le tableau peut avoir n'importe quelle longueur, et les chaînes vides finales seront rejetées.» De http://java.sun.com/javase/6/docs/ api/java/lang/String.html # split% 28java.lang.String,% 20int% 29 –

+0

Oups, oui, je voulais dire 0. Merci! –

+0

+1 pour le réparer :) –

1

Vous pouvez également utiliser potentiellement StringTokenizer pour construire la liste, selon ce que vous devez faire avec:

StringTokenizer st = new StringTokenizer(",,,ZERO;,ONE TWO", ",; ", false); 
while(st.hasMoreTokens()) { 
    String str = st.nextToken(); 
    //add to list, process, etc... 
} 

Comme une mise en garde, cependant, vous devrez définir chaque caractère potentiellement des espaces séparément dans la deuxième argument au constructeur.

2

Presque toutes les installations de séparation intégrées dans le JDK sont cassées d'une manière ou d'une autre. Vous seriez mieux d'utiliser une classe tiers tel que Splitter, qui est à la fois flexible et correcte dans la façon dont il gère les jetons vides et espaces blancs:

Splitter.on(CharMatcher.anyOf(";,").or(CharMatcher.WHITESPACE)) 
    .omitEmptyStrings() 
    .split(",,,ZERO;,ONE TWO"); 

donnera une Iterable < String> contenant « ZERO », "ONE", "TWO"

Questions connexes