Aprender Regex: A Beginner's Guide
En esta guía, aprenderás regex, o sintaxis de expresiones regulares. Al final, serás capaz de aplicar soluciones regex en la mayoría de los escenarios que lo requieren en tu trabajo de desarrollo web.
Las expresiones regulares tienen muchos casos de uso, que incluyen:
- validación de entrada de formularios
- web scraping
- buscar y reemplazar
- filtrar información en archivos de texto masivos como registros
Las expresiones regulares, o regex como se les llama comúnmente, parecen complicadas e intimidantes para los nuevos usuarios. Echa un vistazo a este ejemplo:
/^+@+(?:\.+)*$/
Sólo parece un texto confuso. Pero no desesperes, hay un método detrás de esta locura.
Crédito: xkcd
Te mostraré cómo dominar las expresiones regulares en poco tiempo. Primero, aclaremos la terminología utilizada en esta guía:
- patrón: patrón de expresión regular
- cadena: cadena de prueba utilizada para coincidir con el patrón
- dígito: 0-9
- letra: a-z, A-Z
- símbolo: !$%^&*()_+|~-=`{}:»;'<>?,./
- espacio: un solo espacio en blanco, tabulador
- carácter: se refiere a una letra, un dígito o un símbolo
Básicos
Para aprender regex rápidamente con esta guía, visite Regex101, donde puede construir patrones regex y probarlos contra las cadenas (texto) que usted suministre.
Cuando abra el sitio, tendrá que seleccionar el sabor de JavaScript, ya que es lo que vamos a utilizar para esta guía. (La sintaxis de Regex es mayormente la misma para todos los lenguajes, pero hay algunas diferencias menores.)
Luego, necesita desactivar las banderas global
y multi line
en Regex101. Los cubriremos en la siguiente sección. Por ahora, veremos la forma más simple de expresión regular que podemos construir. Introduzca lo siguiente:
- campo de entrada regex: cat
- cadena de prueba: rat bat cat sat fat cats eat tat cat mat CAT
Tenga en cuenta que las expresiones regulares en JavaScript comienzan y terminan con /
. Si escribiera una expresión regular en código JavaScript, tendría el siguiente aspecto: /cat/
sin comillas. En el estado anterior, la expresión regular coincide con la cadena «cat». Sin embargo, como puede ver en la imagen anterior, hay varias cadenas «cat» que no coinciden. En la siguiente sección, veremos por qué.
Bandas Regex Globales e Insensibles a Mayúsculas y Minúsculas
Por defecto, un patrón regex sólo devolverá la primera coincidencia que encuentre. Si desea obtener más coincidencias, debe activar la bandera global, indicada como g
. Los patrones regex también distinguen entre mayúsculas y minúsculas por defecto. Puede anular este comportamiento activando el indicador de insensibilidad, indicado con i
. El patrón regex actualizado se expresa ahora completamente como /cat/gi
. Como puede ver a continuación, todas las cadenas «cat» han coincidido, incluida la que tiene un caso diferente.
Conjuntos de caracteres
En el ejemplo anterior, aprendimos a realizar coincidencias exactas entre mayúsculas y minúsculas. ¿Qué pasaría si quisiéramos hacer coincidir «bat», «cat» y «fat»? Podemos hacerlo utilizando conjuntos de caracteres, denotados con . Básicamente, se introducen los caracteres que se desea que coincidan. Por ejemplo, at
coincidirá con varias cadenas de la siguiente manera:
Los conjuntos de caracteres también funcionan con los dígitos.
Rangos
Supongamos que queremos coincidir con todas las palabras que terminan en at
. Podríamos suministrar el alfabeto completo dentro del conjunto de caracteres, pero eso sería tedioso. La solución es utilizar rangos como este at
:
Aquí está la cadena completa que se está probando: rat bat cat sat fat cats eat tat cat dog mat CAT
.
Como puedes ver, todas las palabras coinciden como se esperaba. He añadido la palabra dog
sólo para añadir una coincidencia no válida. Aquí hay otras formas de utilizar rangos:
-
Rango parcial: selecciones como
o
.
-
Rango en mayúsculas:
.
-
Gama de dígitos:
.
-
Ámbito de símbolos: por ejemplo,
.
-
Ámbito mixto: por ejemplo,
incluye todos los dígitos, letras minúsculas y mayúsculas. Tenga en cuenta que un rango sólo especifica múltiples alternativas para un solo carácter en un patrón.
Para entender mejor cómo definir un rango, es mejor mirar la tabla ASCII completa para ver cómo se ordenan los caracteres.
Caracteres repetidos
Supongamos que quiere coincidir con todas las palabras de tres letras. Probablemente lo haría así:
Esto coincidiría con todas las palabras de tres letras. Pero, ¿qué pasa si quiere buscar una palabra de cinco u ocho caracteres? El método anterior es tedioso. Hay una forma mejor de expresar ese patrón utilizando la notación de llaves {}
. Todo lo que tiene que hacer es especificar el número de caracteres que se repiten. Aquí hay ejemplos:
-
a{5}
coincidirá con «aaaaa». -
n{3}
coincidirá con «nnn». -
{4}
coincidirá con cualquier palabra de cuatro letras como «puerta», «habitación» o «libro». -
{6,}
coincidirá con cualquier palabra de seis o más letras. -
{8,11}
coincidirá con cualquier palabra de entre ocho y 11 letras. La validación básica de la contraseña se puede hacer de esta manera. -
{11}
coincidirá con un número de 11 dígitos. La validación básica de teléfonos internacionales se puede hacer de esta manera.
Metacaracteres
Los metacaracteres permiten escribir patrones de expresiones regulares que son aún más compactos. Vamos a repasarlos uno por uno:
-
\d
coincide con cualquier dígito que sea igual a -
\w
coincide con cualquier letra, dígito y carácter de subrayado -
\s
coincide con un carácter de espacio en blanco – es decir, un espacio o un tabulador -
\t
coincide con un carácter de tabulación solamente
A partir de lo que hemos aprendido hasta ahora, podemos escribir expresiones regulares como ésta:
-
\w{5}
coincide con cualquier palabra de cinco letras o con un número de cinco dígitos -
\d{11}
coincide con un número de 11 dígitos como un número de teléfono
Caracteres especiales
Los caracteres especiales nos llevan un paso más allá en la escritura de expresiones de patrones más avanzadas:
-
+
: Uno o más cuantificadores (el carácter precedente debe existir y puede estar opcionalmente duplicado). Por ejemplo, la expresiónc+at
coincidirá con «cat», «ccat» y «ccccccccat». Puede repetir el carácter precedente tantas veces como quiera y seguirá obteniendo una coincidencia. -
?
: Cero o un cuantificador (el carácter precedente es opcional). Por ejemplo, la expresiónc?at
sólo coincidirá con «cat» o «at». -
*
: Cero o más cuantificadores (el carácter precedente es opcional y puede estar opcionalmente duplicado). Por ejemplo, la expresiónc*at
coincidirá con «at», «cat» y «ccccccat». Es como la combinación de+
y?
. -
\
: este «carácter de escape» se utiliza cuando queremos utilizar un carácter especial literalmente. Por ejemplo,c\*
coincidirá exactamente con «c*» y no con «ccccccc». -
: esta notación de «negación» se utiliza para indicar un carácter que no debe coincidir dentro de un rango. Por ejemplo, la expresión
bld
no coincidirá con «bald» o «bbld» porque las segundas letras de la a a la c son negativas. Sin embargo, el patrón coincidirá con «beld», «bild», «bold» y así sucesivamente. -
.
: esta notación «do» coincidirá con cualquier dígito, letra o símbolo excepto la nueva línea. Por ejemplo,.{8}
coincidirá con una contraseña de ocho caracteres compuesta por letras, números y símbolos. por ejemplo, «password» y «P@ssw0rd» coincidirán ambos.
A partir de lo que hemos aprendido hasta ahora, podemos crear una interesante variedad de expresiones regulares compactas pero potentes. Por ejemplo:
-
.+
coincide con uno o un número ilimitado de caracteres. Por ejemplo, «c» , «cc» y «bcd#.670» coincidirán. -
+
coincidirá con todas las palabras en minúsculas, independientemente de su longitud, siempre que contengan al menos una letra. Por ejemplo, «libro» y «sala de juntas» coincidirán.
Grupos
Todos los caracteres especiales que acabamos de mencionar sólo afectan a un único carácter o a un conjunto de rangos. ¿Y si queremos que el efecto se aplique a una sección de la expresión? Podemos hacerlo creando grupos con corchetes – ()
. Por ejemplo, el patrón book(.com)?
coincidirá tanto con «libro» como con «libro.com», ya que hemos hecho que la parte «.com» sea opcional.
Aquí tenemos un ejemplo más complejo que se utilizaría en un escenario realista como la validación del correo electrónico:
- patrón:
@\w+\.\w{2,3}(\.\w{2,3})?
- cadena de prueba:
abc.com abc@mail @mail.com @mail.co.ke
Caracteres alternativos
En regex, podemos especificar caracteres alternativos utilizando el símbolo de «pipa» – |
. Esto es diferente de los caracteres especiales que mostramos antes, ya que afecta a todos los caracteres a cada lado del símbolo de la tubería. Por ejemplo, el patrón sat|sit
coincidirá con las cadenas «sat» y «sit». Podemos reescribir el patrón como s(a|i)t
para que coincida con las mismas cadenas.
El patrón anterior puede expresarse como s(a|i)t
utilizando los paréntesis ()
.
Patrones de inicio y fin
Habrás notado que algunas coincidencias positivas son el resultado de una coincidencia parcial. Por ejemplo, si escribí un patrón para que coincida con la cadena «boo», la cadena «book» también obtendrá una coincidencia positiva, a pesar de no ser una coincidencia exacta. Para remediar esto, utilizaremos las siguientes notaciones:
-
^
: colocado al principio, este carácter coincide con un patrón al principio de la cadena. -
$
: colocado al final, este carácter coincide con un patrón al final de la cadena.
Para arreglar la situación anterior, podemos escribir nuestro patrón como boo$
. Esto asegurará que los tres últimos caracteres coincidan con el patrón. Sin embargo, hay un problema que aún no hemos considerado, como muestra la siguiente imagen:
La cadena «sboo» obtiene una coincidencia porque sigue cumpliendo los requisitos actuales de coincidencia de patrones. Para solucionar esto, podemos actualizar el patrón de la siguiente manera: ^boo$
. Esto coincidirá estrictamente con la palabra «boo». Si se utilizan ambos, se aplicarán las dos reglas. Por ejemplo, ^{5}$
coincide estrictamente con una palabra de cinco letras. Si la cadena tiene más de cinco letras, el patrón no coincide.
Regex en JavaScript
// Example 1const regex1=/a-z/ig//Example 2const regex2= new RegExp(//, 'ig')
Si tienes Node.js instalado en tu máquina, abre un terminal y ejecuta el comando node
para lanzar el intérprete de shell de Node.js. A continuación, ejecuta lo siguiente:
Siéntete libre de jugar con más patrones regex. Cuando haya terminado, utilice el comando .exit
para salir del shell.
Ejemplo del mundo real: Validación de correo electrónico
Como conclusión de esta guía, veamos un uso popular de regex, la validación de correo electrónico. (Por ejemplo, podríamos querer comprobar que una dirección de correo electrónico que un usuario ha introducido en un formulario es una dirección de correo electrónico válida.)
Este tema es más complicado de lo que se podría pensar. La sintaxis de la dirección de correo electrónico es bastante simple: {name}@{domain}
. En teoría, una dirección de correo electrónico puede contener un número limitado de símbolos, como #-@&%.
, etc. Sin embargo, la colocación de estos símbolos es importante. Los servidores de correo también tienen diferentes reglas sobre el uso de los símbolos. Por ejemplo, algunos servidores tratan el símbolo +
como inválido. En otros servidores de correo, el símbolo se utiliza para la subdirección de correo electrónico.
Como reto para poner a prueba sus conocimientos, intente construir un patrón de expresión regular que coincida sólo con las direcciones de correo electrónico válidas marcadas a continuación:
# invalid emailabcabc.com# valid email [email protected]@[email protected]@[email protected]# invalid email [email protected]@[email protected]#[email protected]# valid email [email protected]@[email protected][email protected]# invalid domain [email protected]@mail#[email protected]@mail..com# valid domain [email protected]@[email protected]@[email protected]
Tenga en cuenta que algunas direcciones de correo electrónico marcadas como válidas pueden ser inválidas para ciertas organizaciones, mientras que algunas que están marcadas como inválidas pueden estar realmente permitidas en otras organizaciones. En cualquier caso, aprender a construir expresiones regulares personalizadas para las organizaciones para las que trabajas es primordial para satisfacer sus necesidades. En caso de que te quedes atascado, puedes consultar las siguientes soluciones posibles. Tenga en cuenta que ninguna de ellas le dará una coincidencia del 100% en las cadenas de prueba de correo electrónico válidas anteriores.
- Posible solución 1:
^\w*(\-\w)?(\.\w*)?@\w*(-\w*)?\.\w{2,3}(\.\w{2,3})?$
- Posible solución 2:
^((\.,;:\s@"]+(\.\.,;:\s@"]+)*)|(".+"))@((\{1,3}\.{1,3}\.{1,3}\.{1,3}])|((+\.)+{2,}))$
Resumen
Espero que ahora haya aprendido los fundamentos de las expresiones regulares. No hemos cubierto todas las características de las expresiones regulares en esta guía rápida para principiantes, pero deberías tener suficiente información para abordar la mayoría de los problemas que requieren una solución de expresiones regulares. Para aprender más, lea nuestra guía sobre las mejores prácticas para la aplicación práctica de regex en escenarios del mundo real.