Expresiones regulares

Muchos editores y procesadores de textos ofrecen la posibilidad de cambiar una cadena de caracteres por otra. Supongamos que hemos escrito sistemáticamente mv entre vocales en lugar de nv: fácilmente sustituiríamos lo primero por lo segundo, por ejemplo comvenir por convenir. En español aplicaríamos esta sustitución a todas las palabras, y de un golpe de tecla habríamos terminado.

A veces se nos ofrece además imponer la restricción de que la secuencia de caracteres sea una palabra entera. Por ejemplo cambiar magia por majia para dar un toque Nueva Era. Entonces, ¡atención!, la sustitución habrá tenido en cuenta el contexto.

Las expresiones regulares hacen esto y mucho más. No sólo reconocen secuencias de caracteres y palabras enteras, sino también principios de palabra o de línea y en general cualquier esquema. Por ejemplo podríamos buscar todas las palabras que terminan en y utilizando la marca de límite de palabra (\b), así: y\b. Más adelante explicaremos todos los componentes que encontramos en un esquema, intervalos de caracteres ([a-z]), opciones (este|ese), etc.

Además las expresiones regulares nos permiten seleccionar una parte de la secuencia de caracteres encontrada (captura) y utilizarla en la sustitución. Tal vez esto no resulte muy útil en textos redactados pero piénsese en una lista de nombres en la que el nombre de pila apareza al final después de una coma, como es usual, y deseáramos quitar la coma y ponerlo al principio. Querríamos cambiar Domínguez Herrera, Laura por Laura Domínguez Herrera etc. Entonces tendríamos que capturar los apellidos y el nombre y escribir el nombre seguido de los apellidos, sin la coma, claro.

En general las expresiones regulares resultan muy útiles para tratar todo tipo de textos que estructuren la información según un formato. Cumplimos así uno de los objetivos principales de la informática: automatizar las tareas mecánicas. Las aplicaciones irán saliendo solas si manejamos este tipo de textos. En lo que sigue voy a explicar tanto los esquemas como la forma de capturar trozos de cadenas para ponerlas en el texto final.

Abreviaturas

En los esquemas con los que seleccionamos cadenas de caracteres utilizamos las llamadas abreviaturas. Van todas precedidas de una barra hacia atrás que evita que la letra que sigue se interprete literalmente. Si queremos referirnos a una barra inclinada hacia atrás, entonces la escribimos dos veces: \\. Nada más hay que explicar. La lista de abreviaturas es:

Obsérvese que la mayúscula es la negación de la minúscula.

Conjuntos de caracteres y disyunciones

En lugar de un caracter podemos poner un conjunto de caracteres de los cuales puede aparecer uno cualquiera en la selección. La regla es que ha de ir encerrado entre corchetes. Por ejemplo, cualquier vocal no acentuada se representaría mediante [aeiou]. También podemos establecer intervalos separando los extremos mediante un guión. Todas las minúsculas se encajaría mediante [a-z]. Y todas las letras, minúsculas o mayúsculas, mediante [a-zA-Z].

Si entre corchetes aparece el sombrero (^), ninguno de los caracteres que le siguen pueden aparecer. [^0] selecciona cualquier carácter que no sea el cero, y [^ ] selecciona cualquiera que no sea el espacio.

Podemos especificar varias opciones separándolas mediante barra vertical (|), que significa o. Una manera alternativa de especificar todas las letras sería por tanto: [a-z]|[A-Z]. Si especificamos más de dos opciones, intercalamos la barra vertical entre cada par, como en duque|rey|reina, sin añadir espacios de separación.

Cuantificadores

Los elementos de un esquema que no sean literales llevan a la derecha una indicación de cuantas veces puede aparecer. El cuantificador más elemental consiste en un número entre llaves o un mínimo y un máximo separados por coma entre llaves. Por ejemplo, [aeiou]{2} -donde el cuantificador es {2}, por supuesto- encajaría con cualquier vocal doble, y [aeiou]{1,2} encajaría con cualquier vocal simple o doble.

En lugar de números entre llaves se pueden usar: ? (cero o uno), + (uno o más), y * (cualquier cantidad, incluído cero).

Ejemplos de búsqueda

Capturas

Se capturan grupos de caracteres para repetirlos en el texto final. Esto se hace encerrando entre paréntesis las secuencias que nos interesan. Se pueden hacer varias capturas. Las capturas se utilizan o recuperan poniendo en la secuencia de sustitución una barra inclinada seguida de un número, empezando por el 1 (\1, \2 etc.).

Para comprenderlo resolveré el problema propuesto al principio de la lista de nombres en la que el nombre de pila aparecía al final después de coma. Supongamos además que cada nombre ocupa una línea. Tenemos que escribir dos cadenas:

  1. una cadena de búsqueda con dos capturas, la de los apellidos sin la coma y la del nombre: ^([^,]*), (.*);

  2. una cadena de sustitución: \2 \1.

En general se cumple que la cadena de sustitución es lo más fácil. Otros ejemplos de captura con sustitución serían:

Pero para apreciar el gran potencial de las expresiones regulares con sustitución desarrollamos a continuación una serie de ejemplos de tratamiento de textos de HTML y XML.

Captura de mitades en las que partir una palabra

Las siguientes expresiones regulares sirven para capturar dos grupos entre los que se desea partir una palabra insertando la secuencia <breakable/> y llevan todas la substitución \1\2:

Otras expresiones regulares útiles son: