Ir directamente al contenido de esta página
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.
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:
?
: Cero o una ocurrencia.*
: Cero o más ocurrencias.+
: Una o más ocurrencias{n}
: n ocurrencias.{n,m}
: no menos de n ocurrencias y no más de m.{n,}
: un mínimo de n ocurrencias.Para abbcCcddDDeEeffg1 234, vamos a ver unos cuantos resultados:
/[a-d]{2}[A-Z]?/g
: Pido que se busque cualesquiera dos letras en minúscula entre la «a» y la «d» seguidas de una o ninguna mayúscula, de manera global. El resultado es ab,bcC,cd
./[DE][\w]{4,}/g
: Pido cualquier «D» o «E» mayúscula seguida de al menos cuatro caracteres de palabra, de manera global. El resultado es DDeEeffg1
./\wg{2,3}/gi/
: Pido cualquier caracter de palabra seguido de al menos dos y como máximo tres «g», de manera global. El método devuelve null
./\D+/i
: Pido cualquier coincidencia de un caracter que no sea una cifra y que consista en un caracter o más, de manera insensible y no global. El resultado es abbcCcddDDeEeffg
./[a-z]{4}[d]*/g
: Pido cualesquiera cuatro letras seguidas de cero o más «d». Se me devuelve abbc,CcddDD,eEef
.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.
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».
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
.
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
.
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:
^
: Busca la coincidencia al comienzo de una línea.$
: Busca la coincidencia al final de una línea.\b
: Busca en los límites de una palabra.\B
: Busca donde no hay límite de palabra.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
/\w+[\.]?$/i
, es decir, cualquier grupo de caracteres de palabra seguido o no de un punto, situado al final de línea, independientemente de si son mayúsculas o minúsculas./^\w+/i
./\w+sa\b/gi
./\bp\w+/gi
./\B\w+\B/i
? Pues que match()
me devolvería omprueb
, porque es el primer grupo de caracteres de los cuales ninguno se sitúa en un límite de palabra.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…