DIVIDIR UNA TIRA

Cuando empecé a trabajar en Java, me encontré con una desagradable sorpresa. Las funciones para el manejo de tiras de caracteres eran pocas y, con frecuencia, poco potentes. Yo había programado bastante en Rexx y estaba muy satisfecho de sus funciones de manejo de tiras. De hecho, años después, acabé reproducioendo las funciones de tiras de caracteres de Rexx en Java (las podéis descargar aquí).

Pero mi decepción fue total cuando tuve que cortar una tira de caracteres que contenía campos delimitados por comas. La única solución que encontré fue la clase StringTokenizer, pero, en contra de la opinión de Sun, yo le encontraba (y le encuentro) un error grave. Me explicaré. Si tenemos la tira "a,b,c" y la queremos cortar basándonos en la coma como delimitador, podríamos intentar algo parecido a esto:

String input = "a,b,c";

StringTokenizer st = new StringTokenizer(input, ",");
while (st.hasMoreTokens()) {
  System.out.println("'" + st.nextToken() + "'");
}

El resultado es correcto: 'a' 'b' 'c'.

También lo es si la tira a dividir es"a,b, ,c" ya que nos da 'a', 'b', ' ', 'c'.

Los problemas empiezan cuando la tira a dividir es, por ejemplo, "a,b,,c" ya que sólo nos devuelve tres subtiras: 'a', 'b', 'c'. Pasa tres cuartos de lo mismo si la tira a dividir es "a,b,c,". En ambos casos, se deja una tira vacía por contar. Si estamos procesando un archivo que contiene el resultado de la exportación de los registros de una tabla en formato delimitado, estos campos que StringTokenizer ignora alegremente, pueden corresponder a valores null de campos de la tabla. Por lo tanto, nunca podríamos importar correctamente este archivo a otra tabla.

Durante bastante tiempo, Sun ha considerado que éste es el comportamiento correcto y no ha emprendido ninguna modificación de la clase StringTokenizer.

Finalmente, sin embargo, la versión 1.4 del JDK nos proporciona la solución al problema (conste que la clase StringTokenizer se continúa comportando tan mal como siempre) mediante la incorporación de las expresiones regulares.

No entraré aquí en los detalles de la sintaxis de las expresiones regulares. Decir, tan solo, que la clase String las incorpora de manera agradable en algunos de sus nuevos métodos.

Pues bien, la manera correcta de cortar una tira basándose en los delimitadores podría ser esta:

String input     = "a,b,c,";
String delimiter = ",";
String[] fields = input.split(delimiter, -1);
for (int i = 0; i < fields.length; i++) { System.out.println("'" + fields[i] + "'");
}

El resultado, en este caso, sería correcto : 'a', 'b', 'c', ''; es decir, cuatro subtiras y la cuarta vacía.

Obsérvese que el método split() se invoca con dos parámetros. El primero es el delimitador (que puede ser más complicado, ya que es un patrón de expresiones regulares) y el segundo es un entero que indica el número de veces que se aplicará el patrón a la tira. Si tiene un valor positivo, se aplicará tantas veces como indique este parámetro. Así, si la tira a dividir es 'a', 'b', 'c' y especificamos 2, obtendremos sólo dos subtiras: 'a' y 'bc'. Si el entero es negativo, como en nuestro ejemplo, se aplicará tantas veces como sea posible. Si es cero (0) también se aplicará tantas veces como sea posible, pero las tiras finales vacías no se tendrán en cuenta. Así, en nuestro ejemplo, obtendríamos solamente tres subtiras. Por consiguiente, nos interesa especificar un número negativo.

¡Espero que este truco os sea de utilidad!