Hasta ahora, cuando tenías que lidiar con cadenas de texto complejas en Java, la cosa era para echarse a llorar. O te montabas un cristo infumable anidando objetos StringTokenizer y mil llamadas a indexOf y substring —con el código espagueti ilegible que eso conlleva—, o te tocaba bajarte e incluir librerías externas de Apache, como Jakarta ORO o Regexp. Que oye, hacían el trabajo, pero al final era engordar el fichero .jar tontamente y añadir una dependencia más que gestionar a mano cuando subías el código al servidor de producción.
Pero parece que en Sun Microsystems por fin han escuchado las plegarias de los que nos pasamos el día picando código. Llevaba tiempo queriendo actualizar mi entorno, así que hoy por la tarde he dejado descargando la nueva J2SE 1.4 (la famosa Merlin) aprovechando que la conexión me iba medio decente. Después de un buen rato bajando megas, me he puesto a trastear con una de las novedades que más ganas tenía de probar de esta versión: el nuevo paquete java.util.regex.
Sí, amigos, Java por fin tiene soporte nativo para expresiones regulares, al más puro estilo Perl. Se acabó el cacharrear con librerías de terceros para validar un triste email o extraer direcciones IP de un bloque de texto enorme.
La lógica detrás de esto es bastante sencilla, aunque si no estás acostumbrado a la sintaxis de las expresiones regulares, te puede dar una pequeña embolia ver tanta barra invertida junta. Sun nos ha dado dos clases principales para que hagamos la magia: Pattern y Matcher. La primera se encarga de compilar la expresión regular en memoria, y la segunda es el motor que ejecuta esa expresión contra nuestra cadena de texto para ver si hay coincidencias.
Os dejo un snippet rápido de lo que acabo de picar en el UltraEdit para que veáis cómo va el asunto. Básicamente, quería sacar las direcciones IP de una línea de texto de mi log maldito:
import java.util.regex.*;
public class PruebaRegex {
public static void main(String[] args) {
String logLinea = "192.168.1.15 - - [22/Nov/2002:01:45:12 +0100] \"GET /index.html\" 404";
// El patrón para pillar una IP (simplificado, que ya nos conocemos)
String regex = "\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b";
// Compilamos la expresión regular
Pattern patron = Pattern.compile(regex);
// Creamos el buscador contra nuestra cadena de texto
Matcher buscador = patron.matcher(logLinea);
if (buscador.find()) {
System.out.println("¡Bingo! IP encontrada: " + buscador.group());
} else {
System.out.println("Aquí no hay nada, toca seguir buscando.");
}
}
}
Seguramente os habréis fijado en lo de las dobles barras invertidas \\. Esto pasa porque en Java tenemos que escapar la barra invertida dentro de la sintaxis del String antes de podérsela pasar al motor de expresiones regulares. Es un poco dolor de cabeza al principio y queda un pelín feo a la vista, pero te acostumbras rápido.
Lo realmente importante es que esto va rapidísimo al estar integrado de forma nativa. Además, el diseño orientado a objetos está muy bien pensado: compilar el objeto Pattern cuesta bastantes ciclos de reloj, pero si lo haces una sola vez fuera del bucle y reutilizas el objeto Matcher iterando sobre miles de líneas, ahorras muchísima memoria y CPU. Algo que la verdad, mi Pentium con 256 MB de RAM agradece un montón.
Después de un par de horas jugando con esto, tengo que admitir que es una auténtica gozada. Java 1.4 trae un montón de cosas más muy jugosas, como el nuevo sistema de entrada/salida no bloqueante (NIO) o el framework de logging nativo, pero para mí, solo con poder quitarme de encima la tiranía de buscar .jars de Jakarta, ya se justifica la instalación de la SDK.
De cara al futuro, creo que esto va a cambiar bastante cómo procesamos texto en los entornos de desarrollo corporativos. Todo lo que sea estandarizar herramientas potentes y meterlas directamente en el core de la máquina virtual es un acierto brutal por parte de Sun. Obviamente, habrá que ver si las expresiones regulares de Java rinden tan bien como las de lenguajes de scripting puros cuando le metamos gigas y gigas de texto por procesar, pero la base es sólida.
Bueno, cierro ya el chiringuito y me voy a dormir, que mañana a primera hora hay clases.