Expresiones regulares 'para dummies'

^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$
 
Y pensarás... "¿qué narices es esto?". Pues bien, esto es una expresión regular. Es probable que jamás hayas visto ninguna y sin embargo existe y se usa con mucha frecuencia en programas de edición de texto, entornos de desarrollo, páginas web y en UNIX. Pero antes de continuar con ello, veamos qué entendemos por expresión regular.

Sin meternos demasiado en teoría sobre lenguajes regulares ni autómatas finitos vamos a definir una expresión regular (también llamadas regex o patrones) como una cadena de caracteres que describe un conjunto de cadenas de caracteres sin enumerar sus elementos. Dicho de otra forma, es un patrón que genera un conjunto de palabras de un alfabeto (y este alfabeto no necesariamente se compone de letras).

En esta serie de entradas sobre expresiones regulares explicaremos las expresiones regulares de la forma más fácil posible ilustrando con ejemplos siempre que se pueda.

Pues bien, entonces... ¿para qué vamos a querer usar una expresión regular? Supongamos que tenemos una página web en la que queremos poner un formulario que permita a los usuarios contactar con nosotros. Si esto fuera así, es posible que quisieramos contestar a este usuario, por lo que añadiríamos un campo de texto en el que el usuario escribiera el correo donde quiere recibir la respuesta.
Si bien una expresión regular no puede comprobar que los datos son verdaderos, sí que puede decidir si lo que se ha escrito en el campo del e-mail tiene pinta de e-mail o no. Para poder hacer esto tenemos que saber primero qué pinta tienen las cosas que queremos validar. Pongamos un ejemplo para explicar esto:

Entendemos que una dirección de correo electrónico tiene la siguiente estructura: texto@texto.texto. Digamos que para el supuesto anterior, un usuario nos escribe en el campo de e-mail "asdasd". Esto, lógicamente, no es un correo electrónico. Entonces querríamos hacer que el usuario escribiera un correo electrónico válido. Y hasta que no escriba algo de la pinta texto@texto.texto no vamos a darlo por válido. Ahora bien, podríamos haber aceptado una dirección de correo que fuera "foo@bar.asd".
Con una expresión regular sólo podremos validar que una cadena de texto tiene una estructura, pero no que lo que haya escrito exista.

Para acabar con la teoría sobre las expresiones regulares, podemos usarlas como:
  • Motor de búsqueda: buscamos una palabra en un texto (típico Ctrl+F). Ejemplo: buscamos la palabra "byte" en la cadena "mil veinticuatro bytes son un kilobyte". Esto nos daría dos coincidencias, la primera sería en "byte", la segunda en "kilobyte".
  • Lenguaje: utilizamos los caracteres como meta-caracteres. Es decir, no por lo que son, sino por lo que representan. Por ejemplo, queremos encontrar todos los numeros de una cadena de texto. Usamos \d para representar un número cualquiera. Si ahora lo usamos para buscar en "v1d4s_c0ncurr3nt3s", iría encontrando todos los números: 1, 4, 0, 3, 3.
Visto esto, vamos a ver cómo construir las expresiones regulares.

Las expresiones regulares tienen tres tipos de elementos: anclas, cuantificadores y conjuntos de caracteres.

Anclas

Se usan como delimitadores. Existen dos tipos de anclas:
  • ^: este carácter significa comienzo de cadena. Si tuvieramos la expresión ^v encontraría la v inicial de "vidas concurrentes" pero no la v de "concurrentes vidas"
  • $: este carácter significa final de cadena. Si tuvieramos la expresión s$ encontraría la s final de "vidas concurrentes" pero no la s de "bytes a cascoporro".

Cuantificadores

Usamos los modificadores para especificar el número de apariciones de un elemento previo. Existen varios, pero los más imporantes son:
  • +: este carácter significa una o más veces. Si tuviéramos la expresión ac+ encajaría con "acceso" y con "acto" pero no con "vidas" (no hay al menos una c después de la a de vidas).
  • *: este carácter significa ninguna o más veces. Si tuviéramos la expresión ac* encajaría con "acceso", "acto" y "vidas", pero no con "perro" porque no hay una a que venga seguida (o no) de una o más c.
  • ?: este carácter significa como máximo una vez. Si tuviéramos la expresión al?a encajaría con "ala" y "Saavedra", pero no con "hallar".
  • {n,m}: siendo n y m dos números enteros positivos, significa entre n y m veces. Si omitimos n, significa como máximo m veces, y si omitimos m significa como mínimo n veces. Si tenemos la expresión a{2,4} encajará cualquier palabra que contenga entre dos y cuatro a seguidas.
Si a cualquier cuantificador le acompañamos de un ? estaremos haciendo una búsqueda perezosa. Es decir, el mínimo número de apariciones.

Conjuntos de caracteres

Usamos los conjuntos de caracteres para encajar precisamente eso, conjuntos de caracteres:
  • Literales: encajan consigo mismos. La expresión cata encaja en "cata", "percatarse" y en "acatarrado".
  • . : El carácter punto significa cualquier cosa menos un salto de línea. La expresión c.ra encaja con "cara", "encera" y "curarse".
  • []: Usamos los corchetes para especificar una serie de caracteres de los cuales elegimos uno solo. La expresión c[ae]ra encajará con "cara" y "encerar", pero no con "curarse".
  • | : Usamos el carácter de pipe para especificar una serie de opciones. La expresión c(ar|ep)a encaja con "cara" y "cepa", pero no con "cera" ni "capar".
  • - : Siempre que no se encuentre justo después del carácter [, se usa para especificar un rango. La expresión a-e es equivalente a [abcde].
  • ^: si se encuentra justo después del carácter [ significa todo lo que no sea lo que sigue. La expresión [^abc] significa un carácter que no sea una a, una b o una c. Incluye saltos de linea.
  • \w: Este metacarácter significa una letra mayúscula, minúscula, un número o un _. Es equivalente a la expresión [a-zA-Z0-9_].
  • \W: Este metacarácter significa todo lo que no sea una letra mayúscula, minúscula, un número o un _, incluyendo salto de linea. Es equivalente a la expresión [^a-zA-Z0-9_].
  • \d: significa un dígito. Es equivalente a [0-9].
  • \D: significa todo lo que no sea un dígito. Es equivalente a [^0-9].
  • \s: significa un espacio, un tabulador o un salto de linea. Es equivalente a [ \t\r\n].
  • \S: significa todo lo que no sea un espacio, un tabulador o un salto de linea. Es equivalente a [^ \t\r\n].
  • \b: encaja con la posición en la que acaba un \w y donde empieza un \W. Podemos entenderlo como comienzo y final de una palabra.
  • \B: encaja con la posición entre dos caracteres \w\w además de entre dos \W\W.
Podemos usar los paréntesis para agrupar elementos. Esto es interesante para referenciar grupos que queremos repetir. Para referenciar grupos usaremos \1, \2, \3... En otras entradas lo explicaremos aplicándolo a algún ejemplo concreto pero para no dejar esto sin explicar, digamos que queremos hacer un numero capicua de tres cifras. Para ello usaríamos la expresión (\d)\d\1. Esto significa un número, otro número y lo mismo que había en el primer paréntesis.

Además, todos los caracteres se pueden escapar con una \ para evitar su significado especial, incluida la propia \. En otras palabras, la \ no se usa sola.


Si ahora volvemos a la expresión regular que encabezaba esta entrada, seguramente sea más fácil de entender:
^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$
 
Esta expresión tiene 7 partes:
  • ^: hemos dicho que significa comienzo de la cadena.
  • [a-zA-Z0-9._%-]+: esta parte significa al menos una letra minúscula, mayúscula, un dígito, un punto, un _, un % o un -. Esta será la parte del identificador del e-mail.
  • @: el carácter @ en sí mismo.
  • [a-zA-Z0-9.-]+: esta parte significa al menos un caracter alfanumérico, un punto o un -. Lo usamos para validar el dominio de alto nivel. ¿Y por qué aceptamos el punto? Porque un dominio es por ejemplo vidasconcurrentes.com y un subdominio sería blog.vidasconcurrentes.com. Nota: el .com no se valida en esta parte.
  • \. : el carácter punto en sí mismo. Se ha escapado con la \ para quitarle el significado de cualquier caracter excepto salto de linea.
  • [a-zA-Z]{2,6}: esta parte se usa para validar el dominio genérico. Aceptamos mínimo dos caracteres como es, fr o uk y máximo 6 caracteres como travel o museum.
  • $: fin de la cadena.
Como ya dijimos, esto no significa que sea válido, solo que tiene pinta de correo electrónico.

Para acabar os dejo un enlace a otra entrada de nuestro blog donde podéis testear vuestras propias expresiones regulares directamente. Validador expresiones regulares.



Más información:
http://www.regular-expressions.info/