18.5.06

Extrayendo fragmentos de frases con expresiones regulares

Saludos.

Recientemente, desarrollando unas herramientas de prueba, me he encontrado la necesidad de extraer fragmentos de frases compuestas. Lo que buscaba era poder hacer algo así. Si tengo, por ejemplo, estas dos frases.

1: El niño cogió la pelota con las manos.
2: El niño de azul cogió la pelota grande y morada con las dos manos.

Y quiero aplicar el siguiente patrón.

El $1 cogió $2 con $3

El resultado que quiero es:

1: $1 = "niño", $2 = "la pelota", $3 = "las manos"
2: $1 = "niño de azul", $2 = "la pelota grande y morada", $3 = "las dos manos"


Por suerte encontré una manera rápida y fácil de hacer esto en Java con expresiones regulares y Jakarta RegExp (http://jakarta.apache.org/regexp/index.html). Con esta herramienta escribo el patrón utilizando una expresión regular y encerrando entre paréntesis las expresiones que luego quiero recuperar. Así, el patrón anterior se expresaría de la siguiente forma:

El (.+) cogió (.+) con (.+)

El código para aplicar las frases anteriores al patrón se muestra a continuación.



import org.apache.regexp.*;

public class DemoBlog {

public static void main(String[] args) {

String f1 = "El niño cogió la pelota con las manos.";
String f2 = "El niño de azul cogió la pelota grande y morada con las dos manos.";
String re00 = "El (.+) cogió (.+) con (.+)";

RE re = new RE(re00);
System.out.println("Match: " + re.match(f1) );
System.out.println("Match: " + re.match(f2) );
}
}




El código anterior nos muestra por consola que ambas frases casan con la expresión regular.

Ahora, para extraer la parte de la frase que casa con cada una de las expresiones entre paréntesis del patrón, solo tenemos que llamar a getParen(índice), con índice = 1 para obtener el primer paréntesis e índice = 3 para el último. Por ejemplo:


System.out.println("$1 = " + re.getParen(1) );
System.out.println("$2 = " + re.getParen(2) );
System.out.println("$3 = " + re.getParen(3) );


Además, índice = 0 nos devuelve todo el texto (en este caso la frase completa). Si no queremos saber a priori cuanto paréntesis tenemos, podemos ir llamando a getParen(índice) hasta que este nos devuelva null.


Las clases de expresiones regulares (java.util.regexp) que viene a partir del SE 1.4 (y que comentamos en el post de pruebas con JUnit y expresiones regulares) no permiten hacer lo mismo. O, al menos, yo no he encontrado ninguna manera de hacerlo.

También estuve mirando el proyecto ORO de Jakarta (http://jakarta.apache.org/oro/index.html), por si tuviera algo que me permitiera hacer esto mismo de una manera más potente. Pero en un primer vistazo no he visto nada interesante.

No comments: