2012-07-10 3 views
13

sto usando una scheda (/ t) come delimitatore e so che ci sono alcuni campi vuoti nei miei dati ad esempio:Java StringTokenizer.nextToken() salta su campi vuoti

one->two->->three 

Dove -> è uguale alla scheda . Come puoi vedere, un campo vuoto è ancora circondato da tabulazioni. I dati vengono raccolti utilizzando un ciclo:

while ((strLine = br.readLine()) != null) { 
    StringTokenizer st = new StringTokenizer(strLine, "\t"); 
    String test = st.nextToken(); 
    ... 
    } 

Eppure Java ignora questa "stringa vuota" e salta il campo.

C'è un modo per aggirare questo comportamento e forzare java a leggere comunque nei campi vuoti?

+4

Usa 'string.split ("\ t")', invece. –

+3

dai java doc di String tokenizer "StringTokenizer è una classe legacy che viene mantenuta per ragioni di compatibilità anche se il suo uso è sconsigliato nel nuovo codice. Si raccomanda che chiunque cerchi questa funzionalità utilizzi il metodo split di String o java.util.regex pacchetto invece. " – Inquisitive

+1

Solo un avviso che sembra utilizzare 'stringa.split (" \ t ")' non restituirà alcun token vuoto finale alla fine. Se questo è importante, usa 'string.split (" \ t ", -1)'. – Oded

risposta

7

Grazie a tutti.A causa del primo commento sono stato in grado di trovare una soluzione: Sì hai ragione, grazie per il vostro riferimento:

Scanner s = new Scanner(new File("data.txt")); 
while (s.hasNextLine()) { 
     String line = s.nextLine(); 
     String[] items= line.split("\t", -1); 
     System.out.println(items[5]); 
     //System.out.println(Arrays.toString(cols)); 
} 
0

Come si può vedere nel Java Doc http://docs.oracle.com/javase/6/docs/api/java/util/StringTokenizer.html è possibile utilizzare il costruttore public StringTokenizer(String str, String delim, boolean returnDelims) con returnDelimstrue

Quindi ritorna ogni delimitatore come una stringa separata!

Edit:

NON uso in questo modo, come già scritto @npe fuori, StringTokenizer non deve essere utilizzato più! Vedere JavaDoc:

StringTokenizer è una classe eredità che viene mantenuta la compatibilità motivi anche se il suo uso è sconsigliato nel nuovo codice. Si consiglia di che tutti coloro che cercano questa funzionalità utilizzino il pacchetto split di String o il pacchetto java.util.regex.

+0

Sto ancora affrontando il problema di avere più tabulazioni dietro a vicenda (indicando i campi di Blanc) che il valore vuoto NON è inserito nell'array..come posso risolvere? – FireFox

+0

returnDelims restituisce il delimitatore. Questo non risponde alla domanda. –

15

C'è un RFE in the Sun's bug database su questo problema StringTokenizer con uno stato Will not fix.

la valutazione di questo RFE Uniti, cito:

Con l'aggiunta del pacchetto java.util.regex in 1.4.0, abbiamo praticamente obsoleto la necessità di StringTokenizer. Non rimuoveremo la classe per motivi di compatibilità. Ma regex ti dà semplicemente quello di cui hai bisogno.

E quindi suggerisce di utilizzare il metodo String#split(String).

1

userei Guava's Splitter, che non ha bisogno tutti i grandi macchinari regex, ed è più ben educati che il metodo di String split():

Iterable<String> parts = Splitter.on('\t').split(string); 
+3

chiamami paranoico ma non penso davvero che introdurre una nuova dipendenza per qualcosa di così semplice (per non dire incluso nella libreria standard) sia un po 'eccessivo. Apprezzo ancora le informazioni riguardanti lo splitter Guava che non ha bisogno di regex tho :) – posdef

+0

Sono d'accordo, generalmente, ma Guava è così utile e fornisce così tante altre classi utili che fa parte delle mie dipendenze "predefinite" per quasi tutti i miei progetti (a meno che non sia un libreria autonoma molto piccola). –

+0

Guava è fantastico, certo. Non ho ancora esplorato a fondo la suggestione che è Guava, quindi è sempre bello imparare nuove cose a riguardo. – posdef