Ir directamente al contenido de esta página

codexexempla.org

Expresiones regulares (2)

Tabla de contenidos

  1. Cuantificadores
  2. Agrupación
  3. Alternancia
  4. Lookaheads
  5. Límites

Este artículo es la continuación de «Expresiones regulares (1)», del que se recomienda una lectura. Y, como en aquel, recomiendo también que por comodidad se emplee este comparador de expresiones para hacer pruebas sobre los ejemplos.

Cuantificadores

Una vez comprendidas las clases, vamos a ver cómo crear expresiones más complejas, por ejemplo cómo especificar el número de veces que un caracter o clase pueden darse.

Los cuantificadores indican precisamente eso, el número de ocurrencias, o repeticiones, que se esperan del caracter o clase al que acompañan:

Para abbcCcddDDeEeffg1 234, vamos a ver unos cuantos resultados:

Los cuantificadores extienden las posibilidades de las expresiones regulares, pero como se puede observar en los ejemplos, hasta ahora no podemos elegir más que las repeticiones de un caracter o una clase; no podemos especificar las repeticiones de dos clases conjuntas, por ejemplo «cuatro repeticiones de cualquier cifra seguida de cualquier mayúscula». Para eso necesitaríamos poder combinar diversas clases en patrones más complejos.

Agrupación

La primera forma de combinarlas es creando grupos. Un grupo se crea incluyendo un caracter o una clase entre paréntesis:


    var expr = /([0-9][a-z]){2}/gi;
            

La expresión regular significa que la coincidencia deben ser cuatro caracteres, agrupados de forma que el primer par sea un dígito y una letra, y el segundo igual. Si se compara 0d1e2f3g con ésta expresión, match() devolvería 0d1e,2f3g. Sin los paréntesis —[0-9][a-z]{2}—, no devolvería nada, puesto que en la cadena no existe ningún dígito seguido de dos letras.

Igual que para las clases, a los grupos se les puede aplicar un cuantificador. Por ejemplo, si el literal anterior lo comparamos con la expresión /(\d[df])+\w/gi, obtenemos 0d1,2f3, es decir, todas las coincidencias en la que un grupo compuesto por un dígito va seguido de una «d» o una «f», que se repite una o más veces, y va seguido de cualquier caracter de palabra.

Por último, los grupos se pueden anidar. Así, por ejemplo, /([0-9][a-z]([1-4][fg])?){2}/gi devolvería 0d1e2f, es decir, la subcadena en la que se repite dos veces un grupo compuesto por un dígito y una letra seguidos de otro grupo opcional —porque puede aparecer una vez o ninguna— compuesto de un número entre 1 y 4 y la letra «f» o la «g».

Alternancia

En algunas ocasiones, es posible que se quiera buscar una coincidencia de una subcadena de la que una parte puede presentar dos patrones diferentes, que se indican separándolos por medio de una barra vertical (|).

Supongamos que tenemos la cadena 0aAAffGH01DLaJ, y queremos seleccionar grupos compuestos por dos mayúsculas, pero sólo aquellos precedidos por una cifra y una minúscula o por dos minúsculas. Una expresión que los seleccionaría sería la siguiente:


    var expr = /(\d[a-z]|[a-z]{2})[A-Z]{2}/g;
            

Esta expresión por medio de match() devolvería 0aAA,ffGH.

Lookaheads

Los lookaheads1 son similares al ejemplo anterior. Consisten en una clase precedida por una interrogación y un igual (?=) o una interrogación y una exclamación (?!), que expresan, respectivamente, si la clase debe existir o no tras un grupo especificado.

Así, si tuviéramos una cadena con las palabras secesión colisión decisión cremación y quisiéramos encontrar las subcadenas compuestas por cualquier número de letras anteriores a la terminación «sión», se podría crear una expresión como ésta:


    var expr = /[a-z]+(?=sión)/gi
            

Nótese que esta expresión devolvería sece,coli,deci, puesto que el grupo que compone el lookahead es una condición de la búsqueda, pero no parte del grupo a buscar. Si lo que se quisiera hacer fuese localizar las palabras completas que terminan en «sión», habría que crear una expresión regular como /[a-z]+(sión)/gi.

Límites

Hasta ahora, en los ejemplos hemos estado comparando cadenas con las expresiones regulares, pero no hemos de olvidar que uno de los principales usos de las expresiones regulares es trabajar con ellas sobre textos complejos —extraídos de campos de formulario, cargados en un XML, etc.—, por lo que es bueno conocer unas ayudas para trabajar sobre estas unidades de información que nos ofrecen las expresiones regulares: los límites.

Los límites indican una posición específica de un texto extenso en la que buscar la coincidencia que se pretende hallar:

Los límites se indican en la expresión regular en la posición donde se espera encontrarlos. Por ejemplo:


    var expr = /[n-z]+$/i;
            

seleccionaría cualquier grupo de letras entre la «n» y la «z» situado al final de una línea.

Vamos a hacer una pruebas sobre este texto:

Compruebo los lazos entre un tiempo y otro tiempo. El teléfono no suena. Un silencio sin promesas llena indefinidamente el aire. Pero yo no tengo prisa. No hay por qué apresurarse. Estoy preparado. Puedo ir a cualquier parte.2

Con esto termino este segundo artículo de introducción a las expresiones regulares. Por supuesto, es a partir de aquí cuando se empieza de verdad a estudiarlas…

Notas

  1. No he encontrado una traducción que me convenza para este término… Volver
  2. Haruki Murakami, Sputnik, mi amor, p. 245. Tusquets, 2005. Volver
  3. Línea aquí se refiere a la línea de código, es decir, cualquier grupo de caracteres anteriores a un salto de línea o de carro; no tiene nada que ver con las líneas en las que se disponga el texto dependiendo del ancho del elemento en el que se sitúe. Volver

Contacto

En virtud de la Ley Orgánica 15/1999 de Protección de Datos de Carácter Personal le informo de que los datos que proporcione no serán empleados para otro fin que el de responder a su mensaje. En especial, me comprometo a no cederlos a terceros ni a emplearlos para enviar información no solicitada.

Del blog de Digital Icon