2010-09-21 6 views
8

J'essaie d'utilisersplit chaîne ne pas retourner des résultats vides

"value1:value2::value3".split(":"); 

Le problème est que je veux inclure les résultats vierges.

Il retourne: [value1, value2, value3]
Il devrait être: [value1, value2, , value3]

Est-ce que quelqu'un sait le regexp pour résoudre ce problème?

Ok J'ai trouvé la cause du problème. Je lis en fait un fichier texte et il contient cette ligne:

123:;~\&:ST02:M:test:M:4540145::type;12:51253:D:2.2:567766::AL:::::::2.2b 

Quand je traite cette ligne la lecture du fichier texte, il produit le résultat erroné mentionné ci-dessus, qui est elle ne comprend pas de résultats vides dans les cas comme ça: :::::. Mais quand j'utilise la ligne ci-dessus dans un programme de test, il ne compile pas et j'obtiens une "séquence d'échappement invalide". Je pense que c'est à cause du "\ &".

Existe-t-il une solution de contournement à ce problème en utilisant une expression régulière?

Répondre

18

split ne comprend matchs vides dans le résultat, jetez un oeil à la docs here. Cependant, par défaut, les chaînes vides finales (celles situées à la fin du tableau) sont ignorées. Si vous souhaitez également inclure ces éléments, essayez split(":", -1).

+0

Merci ... l'ajout d'un -1 a résolu le problème des caractères spéciaux lors de la lecture d'un fichier texte. Il a également inclus des chaînes vides. – Marquinio

+1

Le lien vers un document ne fonctionne pas. –

1

Je ne vois pas vraiment le grand tirage de split. StringTokenizer fonctionne aussi bien pour la plupart des choses comme ça et va facilement renvoyer les jetons (donc vous pouvez dire qu'il n'y avait rien entre ::). Je souhaite juste que cela fonctionne un peu mieux avec la boucle améliorée, mais cela mis à part, cela ne ferait pas de mal de l'essayer.

Je pense qu'il y a une astuce pour renvoyer vos jetons assortis, mais j'ai passé 20 ans sans apprendre l'expression rationnelle et ce n'est jamais la meilleure réponse à un problème que j'ai abordé (pas que je le ferais En fait, sachez que je ne l'utilise jamais, mais les solutions non-regexp sont généralement trop faciles à battre.)

2

Je pense qu'un StringTokenizer pourrait fonctionner mieux pour vous, YMMV.

+0

Ne pas utiliser StringTokenizer s'il vous plaît. Oracle recommande la méthode split. Cela fait partie de la page de documentation StringTokenizer: 'StringTokenizer est une classe héritée qui est conservée pour des raisons de compatibilité bien que son utilisation soit déconseillée dans le nouveau code. Il est recommandé que quiconque recherche cette fonctionnalité utilise à la place la méthode split de String ou le paquetage java.util.regex. » –

4

Fonctionne pour moi.

class t { 
    public static void main(String[] _) { 
     String t1 = "value1:value2::value3"; 
     String[] t2 = t1.split(":"); 
     System.out.println("t2 has "+t2.length+" elements"); 
     for (String tt : t2) System.out.println("\""+tt+"\""); 
    } 
} 

donne la sortie

$ java t 
t2 has 4 elements 
"value1" 
"value2" 
"" 
"value3" 
1

Utilisez une limite négative dans votre déclaration divisée:

String str = "val1:val2::val3"; 
String[] st = str.split(":", -1); 
for (int i = 0; i< st.length; i++) 
    System.out.println(st[i]); 

Résultats:

val1 
val2 

val3 
1
public static void main(String[] args){ 
    String[] arr = "value1:value2::value3".split(":"); 
    for(String elm:arr){ 
    System.out.println("'"+elm+"',"); 
    } 
    System.out.println(arr.length); 
} 

imprime

'value1', 
'value2', 
'', 
'value3', 
4 

Ce qui est exactement ce que vous voulez. Votre erreur est ailleurs ...

0

Cela devrait fonctionner mais donner StringTokenizer un coup si vous rencontrez toujours des problèmes.

1

utilisant Guava classe « Splitter:

Iterable<String> split = Splitter.on(':').split("value1:value2::value3"); 

Splitter n'omettent pas vide par défaut, mais vous pouvez faire un qui le fait. Bien qu'il semble de ce que les autres disent que ce que vous faites devrait fonctionner aussi bien.

0

Cela fonctionne,

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.File; 
import java.io.IOException; 

public class split { 
public static void main(String[] args) 
{ 
    String data = null; 
    try { 
    BufferedReader br = new BufferedReader(new FileReader(new File("split.csv"))); 
    while((data=br.readLine())!=null) 
    { 
     System.out.println("line:"+data); 
     String[] cols = data.split(":",-1); 
     System.out.println("count:"+cols.length); 
     for(int x=0;x<cols.length;++x) 
     { 
      System.out.println("["+x+"] =("+cols[x]+")"); 
     } 
    } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
} 

Voici un fichier de test,

a:b:c:d:e 
a:b:c:d: 
a:b:c:: 
a:b::: 
a:::: 
:::: 
::::e 
:::d:e 
::c:d:e 
:b:c:d:e 
a:b:c:d:e