2012-07-10 14 views
13

ich eine Registerkarte bin mit (/ t) als Trennzeichen und ich weiß, gibt es einige leere Felder in meine Daten zB:Java StringTokenizer.nextToken() überspringt leere Felder

one->two->->three 

Wo -> die Registerkarte gleich . Wie Sie sehen können, ist ein leeres Feld immer noch korrekt von Tabs umgeben. Die Daten werden mit einer Schleife gesammelt:

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

Doch Java ignoriert diesen „leeren String“ und überspringt das Feld.

Gibt es eine Möglichkeit, dieses Verhalten zu umgehen und Java zu zwingen, in leere Felder zu lesen?

+4

Verwenden 'string.split („\ t“)' statt. –

+3

aus den Java-Dokumenten von String tokenizer "StringTokenizer ist eine Legacy-Klasse, die aus Kompatibilitätsgründen beibehalten wird, obwohl die Verwendung in neuem Code nicht empfohlen wird. Es wird empfohlen, dass diese Funktion die Split-Methode von String oder java.util.regex verwendet Paket stattdessen. " – Inquisitive

+1

Nur ein Heads-up, das aussieht wie 'string.split (" \ t ")' wird am Ende keine abschließenden leeren Token zurückgeben. Wenn das wichtig ist, verwenden Sie 'string.split (" \ t ", -1)'. – Oded

Antwort

7

Sie überhaupt danken.Aufgrund der ersten Kommentar war ich in der Lage, eine Lösung zu finden: Ja, Sie haben Recht, wir danken Ihnen für Ihre Referenz:

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

Wie Sie in der Java-Doc sehen http://docs.oracle.com/javase/6/docs/api/java/util/StringTokenizer.html Sie den Constructor public StringTokenizer(String str, String delim, boolean returnDelims) mit returnDelimstrue

So können sie jedes Trennzeichen als separate String zurückgibt!

Edit:

NICHT verwenden diese Art und Weise, wie @npe bereits getippt, StringTokenizer sollte nicht mehr verwendet werden! Siehe JavaDoc:

StringTokenizer ist ein Vermächtnis-Klasse, die für die Kompatibilität beibehalten wird Gründen obwohl seine Verwendung in neuen Code abgeraten. Es wird empfohlen , dass jemand, der diese Funktionalität sucht, stattdessen die split Methode von String oder das java.util.regex Paket verwendet.

+0

Ich bin immer noch mit dem Problem konfrontiert, dass ich mehrere Tabs hintereinander habe (Blanc Felder anzeigen), dass der leere Wert nicht in das Array gelegt wird .. wie kann ich das beheben? – FireFox

+0

returnDelims gibt das Trennzeichen zurück. Dies beantwortet die Frage nicht. –

15

Es gibt eine RFE in the Sun's bug database über diese StringTokenizer Problem mit einem Status Will not fix.

Die Auswertung dieser RFE Staaten, ich zitiere:

Mit der Zugabe des java.util.regex Paket in 1.4.0, haben wir grundsätzlich die Notwendigkeit StringTokenizer holt. Wir werden die Klasse aus Kompatibilitätsgründen nicht entfernen. Aber regex gibt Ihnen einfach, was Sie brauchen.

Und dann schlägt vor, String#split(String) Methode zu verwenden.

1

würde ich Guava's Splitter verwenden, die nicht alle großen regex Maschinen braucht, und ist mehr artig als split() Methode String:

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

rufen Sie mich paranoid, aber ich glaube wirklich nicht, eine neue Abhängigkeit für etwas so einfach (nicht zu erwähnen, in der Standard-Bibliothek enthalten) einzuführen ist ein bisschen ein Overkill. Ich schätze immer noch die Informationen über Guava Splitter brauchen keine Regex tho :) – posdef

+0

Ich stimme zu, in der Regel, aber Guava ist so nützlich und bietet so viele zusätzliche nützliche Klassen, dass es Teil meiner "Standard" Abhängigkeiten für fast alle meine Projekte ist (es sei denn es ist ein sehr kleine eigenständige Bibliothek). –

+0

Guava ist definitiv großartig. Ich habe die Großartigkeit von Guava noch nicht vollständig erforscht, daher ist es immer schön, neue Dinge darüber zu lernen. – posdef