2012-07-10 30 views
13

que estoy usando una pestaña (/ t) como delimitador y sé que hay algunos campos vacíos en mis datos, por ejemplo:Java StringTokenizer.nextToken() salta sobre los campos vacíos

one->two->->three 

Dónde -> es igual a la pestaña . Como puede ver, un campo vacío sigue rodeado correctamente por pestañas. Los datos se recogen usando un bucle:

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

Sin embargo, Java ignora esta "cadena vacía" y se salta el campo.

¿Hay alguna manera de eludir este comportamiento y obligar a Java a leer en campos vacíos de todos modos?

+4

Use 'string.split ("\ t")' en lugar. –

+3

de los documentos java de String tokenizer "StringTokenizer es una clase heredada que se conserva por razones de compatibilidad, aunque se desaconseja su uso en el nuevo código. Se recomienda que cualquiera que busque esta funcionalidad utilice el método de división de String o el java.util.regex paquete en su lugar ". – Inquisitive

+1

Solo un aviso de que parece que 'string.split (" \ t ")' no devolverá ningún token vacío al final. Si eso es importante, use 'string.split (" \ t ", -1)'. – Oded

Respuesta

7

Gracias a todos.Debido a la primera observación que era capaz de encontrar una solución: Sí tienes razón, gracias por su referencia:

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

Como se puede ver en el Java Doc http://docs.oracle.com/javase/6/docs/api/java/util/StringTokenizer.html puede utilizar el Constructor con public StringTokenizer(String str, String delim, boolean returnDelims)returnDelimstrue

Así que vuelve cada delimitador como una cadena separada!

Editar:

NO utilización de esta manera, como ya se @npe escrito a máquina, StringTokenizer no debe utilizarse más! Ver JavaDoc:

StringTokenizer es una clase de legado que se conserva por compatibilidad razones aunque su uso no se recomienda en nuevo código. Se recomienda que cualquiera que busque esta funcionalidad utilice el método split de String o el paquete java.util.regex en su lugar.

+0

Todavía me enfrento con el problema de que tengo varias pestañas una detrás de otra (indicando campos en blanco) que el valor en blanco NO se pone en la matriz. ¿Cómo puedo solucionar esto? – FireFox

+0

returnDelims devuelve el delimitador. Esto no responde la pregunta. –

15

Hay un RFE in the Sun's bug database sobre este problema StringTokenizer con un estado Will not fix.

La evaluación de estos estados RFE, cito:

Con la adición del paquete java.util.regex en 1.4.0, tenemos básicamente obsoleto la necesidad de StringTokenizer. No eliminaremos la clase por razones de compatibilidad. Pero regex le brinda simplemente lo que necesita.

Y luego sugiere utilizar el método String#split(String).

1

me gustaría utilizar Guava's Splitter, que no necesita toda la gran maquinaria de expresiones regulares, y es más comporta bien que el método de cadena split():

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

llámame paranoico pero realmente no creo que introducir una nueva dependencia por algo tan simple (sin mencionar incluido en la biblioteca estándar) es un poco exagerado. Todavía aprecio la información sobre el divisor de guayaba que no necesita expresiones regulares aunque :) – posdef

+0

Estoy de acuerdo, en general, pero la guayaba es tan útil y proporciona tantas clases útiles adicionales que es parte de mis dependencias "predeterminadas" para casi todos mis proyectos (a menos que sea biblioteca autónoma muy pequeña). –

+0

La guayaba es increíble, seguro. Todavía no he explorado por completo la maravilla que es la guayaba, así que siempre es bueno aprender cosas nuevas al respecto. – posdef

Cuestiones relacionadas