2012-09-12 13 views
5

Ho un problema apparentemente semplice di dividere una virgola separati String in token, per cui l'uscita dovrebbe comprendere gettoni vuote nei casi in cui:Tokenising una stringa contenente gettoni vuoti

  • Il primo carattere della String è una virgola .
  • L'ultimo carattere nel numero String è una virgola.
  • Si verificano due virgolette consecutive.

Ad esempio, per la String: ",abd,def,,ghi," dovrebbe fornire l'output: {"", "abd", "def", "", "ghi", ""}.

Ho provato a utilizzare String.split, Scanner e StringTokenizer per questo, ma ognuno fornisce un output indesiderato diverso (esempi di seguito). Qualcuno può suggerire una soluzione elegante per questo, preferibilmente utilizzando le classi JDK? Ovviamente potrei codificare qualcosa da solo ma sento che mi manca qualcosa su uno dei tre approcci menzionati. Notare che il delimitatore è un valore fisso String sebbene non necessariamente una virgola, né un singolo carattere.

Esempio di codice

import java.util.*; 

public class Main12 { 
    public static void main(String[] args) { 
    String s = ",abd,def,,ghi,"; 
    String[] tokens = s.split(","); 

    System.err.println("--- String.split Output ---"); 
    System.err.println(String.format("%s -> %s", s, Arrays.asList(tokens))); 

    for (int i=0; i<tokens.length; ++i) { 
     System.err.println(String.format("tokens[%d] = %s", i, tokens[i])); 
    } 

    System.err.println("--- Scanner Output ---"); 

    Scanner sc = new Scanner(s); 
    sc.useDelimiter(","); 
    while (sc.hasNext()) { 
     System.err.println(sc.next()); 
    } 

    System.err.println("--- StringTokenizer Output ---"); 

    StringTokenizer tok = new StringTokenizer(s, ","); 
    while (tok.hasMoreTokens()) { 
     System.err.println(tok.nextToken()); 
    } 
    } 
} 

uscita

$ java Main12 
--- String.split Output --- 
,abd,def,,ghi, -> [, abd, def, , ghi] 
tokens[0] = 
tokens[1] = abd 
tokens[2] = def 
tokens[3] = 
tokens[4] = ghi 
--- Scanner Output --- 
abd 
def 

ghi 
--- StringTokenizer Output --- 
abd 
def 
ghi 

risposta

12

Passare un -1 per split come limit argomento:

String s = ",abd,def,,ghi,"; 
String[] tokens = s.split(",", -1); 

Quindi l'array di risultati includerà eventuali stringhe vuote finali.

Dal javadocs:

Se [limite] non è positiva, allora il modello viene applicato come numero di volte possibile e la matrice può avere qualsiasi lunghezza. Se [il limite] è zero, il pattern verrà applicato il maggior numero possibile di volte, l'array può avere una lunghezza qualsiasi e le stringhe vuote finali verranno scartate.

Calling split(regex) agisce come se l'argomento è limit0, così trascinamento stringhe vuote vengono scartati.