viernes, 5 de agosto de 2011

Eliminación de espacios de sobra en cadenas de texto

Este tema es algo simple, pero dado que existen algunas alternativas, y es algo interesante a la hora de realizar trabajos con cadenas de texto, expongo aquí métodos en Java para que, en una cadena de caracteres, solo exista un espacio entre cada palabra y la cadena empiece y termine por una letra.

Una de las primeras formas que se nos podría ocurrir, sería la siguiente:

String cadena = new String("   Hola   esto es   una prueba      ");
cadena = cadena.trim();
String[] nueva = cadena.split(" +");

De esta forma, tendríamos un array de cadenas que corresponderían a la frase original, y, a la hora de reconstruir la frase podríamos realizarlo de la siguiente manera:

StringBuffer frase = new StringBuffer();
frase.append(nueva[0]);
for(int i = 1;i < nueva.length;i++)
    frase.append(" " + nueva[i]);

Lo que estamos realizando en este código es: en primer lugar llamamos al método trim() de la clase String, que elimina espacios por delante y por detrás de la cadena en caso de que los haya. Posteriormente llamamos al método split() y le pasamos como parámetro una expresión regular, en este caso " +" que es una expresión regular que reconoce las cadenas que poseen uno o más espacios. A continuación recorremos el array devuleto por split y vamos concatenando en un StringBuffer (se podría realizar concatenando en una variable String con el operador +, pero por temas de eficiencia es preferible y muy recomendable realizarlo con StringBuffer).

De esta forma, en la variable frase, que es de tipo StringBuffer, tendríamos la cadena inicial, pero sin espacios al principio ni al final y además con un único espacio entre fases.

Este método es correcto y realiza su función, pero hemos tenido que escribir 6 líneas de código para realizarlo además de declarar un stringbuffer y parece que hemos tenído que darle demasiadas vueltas.


Una segunda forma de realizar este cometido podría ser la siguiente:

String texto = new String("    Hola    esto   es una prueba         de eliminar espacios  ");
texto = texto.replaceAll(" +", " ");
texto = texto.trim();

Lo que hacemos es reemplazar con el método replaceAll() todas las cadenas especificadas por el primer parámetro, que es una expresión regular, y las sustituimos por el segundo parámetro, es decir, reemplazamos todos los espacios por un único espacio. Por ejemplo, sí tenemos: "El         jamón     ", tras aplicar este método nos quedaría lo siguiente: "El jamón ". Por tanto, a continuación tan solo deberíamos aplicar el método trim() y conseguiríamos lo que andábamos buscando.

En este caso, tenemos tan solo dos líneas de código (no cuento la declaración del objeto) y de nuevo realiza correctamente su cometido. Incluso de esta manera sería más eficiente que la propuesta anteriormente.

Una última forma podría ser empleando la clase StringTokenizer, y sería de la siguiente manera:

String texto = new String("    Hola esto   es  una prueba      de     eliminar      espacios                    ");
StringTokenizer tokenizer = new StringTokenizer(texto, " ");
StringBuffer frase = new StringBuffer();
if(tokenizer.hasMoreTokens()){
    frase.append(tokenizer.nextToken());
    while(tokenizer.hasMoreTokens())
        frase.append(" " + tokenizer.nextToken());
}

De nuevo en la variable frase, tendríamos el contenido.

Aquí estamos declarando una variable de tipo StringTokenizer y le pasamos como parámetro al constructor el texto y el delimitador de cada token. Por último, si queremos reconstruir la frase hacemos lo especificado arriba y la conseguiríamos.

Este método no me agrada tanto como el anterior, ya que hay que realizar muchas más comprobaciones (la del if se ejecutará siempre y las del bucle while tantas como tokens hayan a partir del primero) además de que se realizan muchas más llamadas a métodos que en el anterior caso.

No puedo decir que una sea más eficiente que la otra ya que debería saber el coste de cada método, pero por intuición (cosa que puede estar equivocada) diría que el 2º método sería el más eficiente.

Espero que sea de utilidad a todo aquel que venga a parar aquí.

Saludos y suerte.

No hay comentarios:

Publicar un comentario