Expresiones regulares

Las expresiones regulares son una notación especial que permite al usuario instruir la computadora para hacer operaciones relativamente poderosas cuando se debe trabajar con texto puro, por ejemplo en los siguientes escenarios: diálogos de buscar/reemplazar de los editores de texto, comandos del sistema operativo (como grep en Unix), y lenguajes de programación como Perl, Ruby y JavaScript.

Una expresión regular es un patrón que al aplicarse a un texto dado, indica si el patrón empata o parea (hace "match") con algún segmento del texto, en tal caso, la expresión regular aplica, y al texto que parea se le puede hacer modificaciones indicadas en la misma expresión regular.

Formalmente hablando, una misma expresión regular se puede confrontar con un conjunto infinito de textos, y dividirá a estos en dos subconjuntos: los textos que hacen "match" y los que no. Nótese que cada uno de estos subconjuntos podrían tener cero, uno, n, o todos los textos confrontados.

En los lenguajes de programación interpretados como Perl, Ruby o JavaScript se pueden crear expresiones regulares literales, encerrándolas entre dos slash, por ejemplo, /mayo/ es una expresión regular que hace "match" con todos los textos que contengan la cadena "mayo" en algún lugar, pero respetando las mayúsculas y minúsculas. Una segunda expresión se puede escribir tras otro slash, por ejemplo /mayo/junio/, la cual indica reemplazar todas las ocurrencias de "mayo" por "junio".

Ejercicio 1. ¿Cuáles de los siguientes textos harán "match" con la expresión regular /mayo/?

Hoy es 06 de Mayo.
En mayo inicia el invierno.
El mayordomo quebró el frasco de mayonesa.
¿Por qué desaparecieron los mayas?
Diferencias entre guacamayos y lapas.

En una expresión regular se pueden utilizar secuencias de escape para representar los caracteres especiales: nulo ('\0'), tabulador ('\t') y cambio de línea ('\n').

Todo el texto que escriba en una expresión regular debe hacer "match" exactamente, a excepción de los metacaracteres, que tienen un significado especial dentro del patrón. Por ejemplo, el punto (.) hace "match" con cualquier carácter, excepto el cambio de línea ("\n"). Así, /ma.a/ hace "match" con "maya", "mala", "mapa", "ma=a", "ma.a" _y cualquier string que empiece con "ma", seguido por cualquier carácter excepto "\n", seguido por una "a". Y si se quiere encontrar un punto literal dentro del texto, se deberá anular su significado especial con una secuencia de escape, por ejemplo: /3\.141592/, la cual no consta de ningún metacarácter.

Ejercicio 2. ¿Cuáles de los siguientes textos harán "match" con la expresión regular /.ue./?

Vuela, vuela
Eureca, el ungüento sirvió!
SE ARRANCAN MUELAS
ue. es la sigla de la unión europea
Ya se fue

Hay tres metacaracteres cuantificadores: *, + y ?. El metacarácter asterisco * hace "match" si el ítem precedente se encuentra cero o más veces en el texto. Así /\.\t*/ hace "match" con un punto, seguido de cero, uno, dos o más tabuladores. El metacarácter cuantificador + hace "match" si el ítem precedente aparece una o más veces en el texto. Por ejemplo, la expresión /.+/ va a hacer "match" con cualquier número de caracteres excepto el cambio de línea, es decir, va a hacer "match" con una línea de texto completa. El metacarácter ? indica que el ítem precedente es opcional, así /Palm ?OS/ va a hacer "match" únicamente con dos textos: "Palm OS" y "PalmOS".

Los metacaracteres de agrupamiento son los paréntesis redondos (). Mientras /gato+/ hace "match" con algo como "gatoooo"; /(gato)+/ hace "match" con textos como "gatogatogato". El texto que hizo "match" por una expresión entre paréntesis (llamada grupo) puede ser reutilizado con referencias previas (back references) en notación \G ó \{G} donde G es el número de grupo en la expresión regular. Por ejemplo: /(.)/ hace "match" con cualquier carácter que no sea cambio de línea, y /(.)\1/ parea cualquier carácter que aparezca seguido dos veces, como "aa", "bb", "%%".

Por ejemplo, el patrón /(.)\1/ parea cualquier carácter seguido de sí mismo. Si se aplica a la cadena "abba", la primera 'a' hará match con el (.) pero la 'b' no lo hará con \1 y falla. El procesador de expresiones regulares pasará al siguiente carácter en el texto, es decir, tratará de parear la misma expresión regular contra el texto "bba", el cual si hará match.

Ejercicio 3. ¿Cuáles de los siguientes textos pareará la expresión /(.)(.).\2\1/

Abracadabra
La guanábana es un tipo de anona de mayor tamaño
Oferta: $99.99. Llame ya!
Los palíndromos y los números capicúa

Si en la expresión regular hay varios grupos de paréntesis redondos, incluso anidados, es fácil determinar cual número corresponde a cada uno. Simplemente se cuenta los paréntesis que abren en la expresión regular de izquierda a derecha.