Expresiones regulares

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail

Todos sabemos lo que son las expresiones regulares. Se trata de patrones de secuencias de caracteres que empleamos para comprobar si una cadena de texto se ajusta a un formato específico. Por ejemplo, puede que una cadena deba contener dígitos numéricos, pero no espacios en blanco, o letras o signos de puntuación. O podemos querer comprobar que una cadena contiene una dirección de correo electrónico correctamente escrita.

En estos casos creamos un patrón que define el formato al que debe ajustarse una cadena y luego lo comparamos con la misma. La forma de hacer estas comparaciones depende de cada lenguaje específico. En esta serie de artículos conoceremos el modo de emplear las expresiones regulares en los dos lenguajes de script más extendidos en el desarrollo web: JavaScript y PHP. Sin embargo, los patrones que se emplean en las expresiones regulares para comprobar la coincidencia con tal o cual formato es siempre el mismo, con independencia de que se usen luego estas expresiones en Python, Java, PHP, C++, o cualquier otro lenguaje.

LAS EXPRESIONES REGULARES

Ya hemos comentado que las expresiones regulares (conocidas cómo regex o regexp) son patrones para validación de datos. Eso lo sabemos todos. Y todos hemos aprendido, seguramente, cómo se construyen esos patrones. Sin embargo, al no ser algo de uso cotidiano (al menos en la mayoría de los casos), no siempre recordamos lo necesario cuando nos hace falta crear una expresión regular. En este artículo vamos a recopilar, a modo de “chuleta”, la estructura de las expresiones regulares, de modo que podamos tenerlo a mano siempre que nos haga falta.

En una expresión regular podemos incluir caracteres que deberán aparecer en el dato a validar, como letras, dígitos o signos de puntuación. Podemos indicar que dichos caracteres estén en un rango determinado (por ejemplo, dígitos del 6 al 9, o letras de la C a la R). También podemos indicar que tal o cual carácter aparezca al principio o al final de un dato a validar, o que se encuentre repetido determinado número de veces. Además, podemos agrupar partes de la expresión regular, de tal forma que se evalúe el dato a validar en un orden específico.

La tabla que parece a continuación es un compendio de los distintos patrones que se pueden incluir en una expresión regular.

PATRÓN USO
. El punto se emplea como un comodín para buscar un carácter cualquiera, en una posición determinada o no, en el dato a validar. Si queremos usarlo para buscar, específicamente, un punto, deberemos escaparlo con la barra invertida (\. en lugar de .).
* El asterisco indica que el carácter, o secuencia de caracteres, que le precede puede aparecer cualquier número de veces (incluso ninguna, lo que le hace un operador extremadamente ambiguo). Si lo que queremos es buscar, específicamente, un asterisco, deberemos escaparlo con la barra invertida (\* en lugar de *).
| Alternativa. Es un operado que nos permite buscar un patrón u otro, de forma que se validará un dato cuando incluya cualquiera de los patrones que se buscan. Por ejemplo, dada una expresión regular como azul|rojo, dará por válidas las frases El coche es azul o El camión es rojo, pero no validará El coche es verde o La moto es roja.
? El signo de interrogación indica que el carácter, o secuencia de caracteres, que le precede puede aparecer una vez, o ninguna, pero no más de una vez en el dato a validar. Por ejemplo, el patrón o? validaría Hla y también Hola, pero no Hoola. Si queremos buscar en el dato a validar específicamente el carácter ? deberemos escaparlo con la barra invertida (\? en lugar de ?).
+ Este operado indica que el carácter, o secuencia de caracteres, que le precede debe aparecer, al menos, una vez. Por ejemplo, el patrón i+ validaría Junio o Noviembre, pero no Enero. Si queremos buscar, específicamente, el carácter + deberemos escaparlo con la barra invertida (\+ en lugar de +).
() Los paréntesis se usan para agrupar caracteres, o secuencias de caracteres, o para establecer precedencias. Por ejemplo, el patrón (f|g)ruta validaría un dato que contenga fruta o gruta. Si queremos buscar específicamente un carácter ( o ) deberemos escaparlo con la barra invertida (\( en lugar de (, o \) en lugar de )). Si queremos buscar una secuencia formada por los dos paréntesis (abierto y cerrado), uno a continuación del otro, deberemos escapar cada uno de ellos (\(\) en lugar de ()).
\

La barra invertida es un operador extremadamente útil en la construcción de expresiones regulares. Permite escapar cualquier operador (ya hemos visto algunos casos en esta tabla) de forma que deje de ser un operador como tal, y represente un carácter específico.

Además, permite crear determinadas secuencias para buscar. Por ejemplo, si creamos un patrón que incluya \t no buscará la letra t, sino una tabulación. Uno de los usos, en este sentido, más útiles, es especificar un carácter mediante su código Unicode. Por ejemplo, el patrón \u03A9 buscará el carácter Ω. Es útil cuando hay que buscar caracteres que no están disponibles en el teclado que empleamos. Se puede encontrar una tabla Unicode en este enlace. Una relación más completa de secuencias formadas con la barra invertida puede encontrarse a continuación de esta tabla.

Si queremos buscar específicamente una barra invertida, deberemos escapar dicho carácter con otra barra invertida (\\ en lugar de \).

[rango] Los corchetes permiten definir un rango de caracteres a buscar. Por ejemplo, el patrón [a-f] buscará cualquier letra minúscula que esté entre la a y la f; el patrón [A-F] buscará cualquier letra mayúscula que esté entre la A y la F; el patrón ([A-F]|[a-f]) buscará cualquier letra que esté entre la A y la F, y también entre la a y la f. Esto puede expresarse de forma simplificada cómo [A-Fa-f]. Si queremos buscar específicamente un corchete, deberemos escaparlo (\[ en lugar de [, o \] en lugar de ]).
{} Este operador contiene un valor numérico, o rango de valores numéricos, que indican el número de veces que el carácter o secuencia precedente debe aparecer en un dato, para que sea validado. Por ejemplo, el patrón a{3} validará un dato cuando, dentro del mismo, aparezca la secuencia aaa. El patrón [1-5]{2,4} validará un dato si encuentra una secuencia de entre dos y cuatro dígitos, siempre que estos estén comprendidos entre el 1 y el 5. Es decir, validará 123, pero no 567 (ya que de los dígitos comprendidos entre el 1 y el 5 solo aparece uno, y buscamos entre dos y cuatro). Si queremos encontrar específicamente los caracteres { o } deberemos escaparlos (\{ en lugar de {, o \} en lugar de }).
$ Este operador establece que el carácter, o rango de caracteres, que le precede es el último de la línea. Por ejemplo, el patrón A$ validará las cadenas que terminen con A mayúscula. Es especialmente útil cuando se están validando datos multilínea, por ejemplo, ya que el patrón ((\r|\n)\.)$ buscará los finales de cada línea. Si lo que queremos es buscar este carácter específicamente, deberemos escaparlo con una barra invertida (\$ en lugar de $).
^

Al contrario que el anterior, este operador busca coincidencia con el principio de la línea. En este caso, de modo excepcional, el carácter o secuencia que se busca se establece a la derecha del operador, en lugar de precediéndole, cómo ocurre con otros operadores. Por ejemplo, el patrón ^[a-z] validará un dato que empiece por una letra minúscula.

En combinación con los cochetes, su uso cambia. En este caso se buscan NO coincidencias con el carácter o rango indicado. Por ejemplo, el patrón [^\d] buscará coincidencias con caracteres que no sean dígitos, pero no necesariamente al principio del dato a validar. Si debiéramos buscar esta coincidencia en la posición inicial, el patrón sería ^[^\d].

Si lo que queremos es buscar este carácter específicamente, deberemos escaparlo con una barra invertida (\^ en lugar de ^).

! Este operador actúa como negación del carácter, secuencia o rango que le sucede. Por ejemplo, el patrón !\d buscará caracteres que no sean dígitos. Si lo que queremos es buscar este carácter específicamente, deberemos escaparlo con una barra invertida (\! en lugar de !).

Como hemos comentado anteriormente, a continuación incluimos una relación de aquellas secuencias de barra invertida (\) que tienen un significado especial a la hora de construir expresiones regulares.

SECUENCIA USO
\t Representa un tabulador.
\r Representa el “retorno de carro” o “regreso al inicio”, es decir, el punto antes del primer carácter de la línea. (1)
\n Representa la “nueva línea” el carácter por medio del cual una línea da inicio. (1)
\f Representa un salto de página.
\x Especigfica un carácter mediante su código ASCII o ANSI. Por ejemplo, si se busca el símbolo de derechos de autor (©) y el dato a validar utiliza el conjunto de caracteres Latin-1, el patrón será \xA9. La cuestión es que, por ejemplo, la mayoría de los datos en Internet se usan hoy día en formato UTF-8, pero no podemos dar esto por sentado, por lo que este tipo de patrones podría dar lugar a una inexactitud.
\u Especifica un carácter mediante su código Unicode. Por ejemplo, el patrón \u03A9 buscará el carácter Ω.
\d Representa un dígito del 0 al 9.
\w Representa cualquier carácter alfanumérico, es decir, que no sea un espacio en blanco ni signo de puntuación.
\s Representa un espacio en blanco.
\D Representa cualquier carácter que no sea un dígito del 0 al 9.
\W Representa cualquier carácter no alfanumérico.
\S Representa cualquier carácter que no sea un espacio en blanco.
\A Representa el inicio de la cadena. No un carácter sino una posición. Sin embargo, a este efecto, en las expresiones regulares es más normalizado emplear ^.
\Z Representa el final de la cadena. No un carácter sino una posición. Sin embargo, a este efecto, en las expresiones regulares es más normalizado emplear $
\b Marca la posición de una palabra limitada por espacios en blanco, puntuación o el inicio/final de una cadena.
\B Marca la posición entre dos caracteres alfanuméricos o dos no-alfanuméricos.

FLAGS

Existen un par de flags, o modificadores, que pueden alterar el comportamiento normal de una expresión regular. Se pueden colocar al principio o al final de la expresión, dependiendo del lenguaje empleado.

FLAG USO
i Hace que la comparación sea insensible a mayúsculas y minúsculas. Así, con este flag, los patrones [a-z] y [A-Z] resultan equivalentes. 
g Se emplea para detectar múltiples ocurrencias de un patrón en un dato a validar. Por defecto, sólo se busca la primera coincidencia.
m Trata los delimitadores de inicio y fin (^ y $) como múltiples líneas de texto (es decir, busca el inicio o fin de cada línea delimitada por \n o \r, no sólo al inicio o fin de todo el dato a validar).

EXPRESIONES REGULARES HABITUALES

Construir expresiones regulares, cuando se conocen los distintos patrones descritos en este artículo, es una tarea sencilla. Sin embargo, existen expresiones que son de uso muy habitual (por ejemplo, para validar una URL, o una dirección de correo electrónico), que ya están escritas y funcionan perfectamente, por lo que no es necesario reinventar la rueda. Aquí te ofrezco las más habituales.

EXPRESIÓN USO
^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$ Valida un dato de correo electrónico.
^(http|https|ftp)\:\/\/[a-z0-9\.-]+\.(([a-z]{2,4})+)$ Valida una URL.
(?:\d{3}|\(\d{3}\))([-\/\.])\d{3}\1\d{4} Valida un teléfono (incluso el prefijo entre paréntesis).
^([A-Z]{1}[a-zñáéíóú]+[\s]*)+$ Valida un nombre propio.
^\d{2}\/\d{2}\/\d{4}$ Valida una fecha con formato dd/mm/aaaa. Sin embargo esta es una validación muy “traida por los pelos”, ya que una fecha a todas luces incorrecta, como 65/34/2017 será dada por buena. Las expresiones regulares no son la mejor manera de validar fechas, debiendo recurrirse a otras técnicas.
^[0-9]+$ Valida datos formados exclusivamente por dígitos numéricos, como suele ser el caso de los identificadores únicos de registros.
^http:\/\/(localhost|127\.0\.0\.1) Valida una URL local (localhost).
^\d{8}[a-zA-Z]{1}$ Valida un NIF.
^[a-zA-Z]{1}\d{7}[a-zA-Z0-9]{1}$ Valida un CIF.
^[XxTtYyZz]{1}[0-9]{7}[a-zA-Z]{1}$ Valida un NIE.
^4[0-9]{3}-?[0-9]{4}-?[0-9]{4}-?[0-9]{4}$ Valida una tarjeta VISA.
^5[1-5][0-9]{2}-?[0-9]{4}-?[0-9]{4}-?[0-9]{4}$ Valida una tarjeta MASTERCARD.

En el próximo artículo de esta serie hablaremos de la forma de emplear expresiones regulares en JavaScript, para validación de datos en el lado del cliente (aunque lo que comentemos puede ser empleado también en API’s de NodeJS).

     

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *