48

Expresiones regulares: qué son, cómo se usan y ejemplos

29077Puntos

hace 3 años

Las expresiones regulares son patrones que usaremos para encontrar una o varias combinaciones de caracteres en un texto. Esta, sin embargo, es una definición incompleta. Hoy iremos más allá.

Conocerás por qué RegEx como tal no existe, qué tiene que ver RegEx con un problema profundo de las matemáticas, cómo se relaciona eso con un millón de dólares y vamos a terminar construyendo un chatbot usando únicamente expresiones regulares.

¿Te interesa? Empecemos:

¿Qué es RegEx?

Antes de empezar, definamos adecuadamente el término. RegEx como tal no existe. Hablar de expresiones regulares es como hablar de SQL. No existe un único SQL, sino que todo el mundo toma un poco de él para usarlo a su manera y, aunque sí encontramos similitudes entre PostgreSQL, MySQL y Microsoft SQL, al final son cosas distintas.

Una expresión regular es un conjunto de caracteres que forman un patrón. Este patrón sirve para buscar y comparar strings (. Encontrado el patrón, es posible usar un segundo patrón para remplazar los strings encontrados de ser necesario.

¿Puedes darme un ejemplo?

Esto es una expresión regular, esta simple palabra ya se considera un patrón válido.

hello

Vamos por otro ejemplo de RegEx: imaginemos que tengo un bot de telegram un poquito básico y quiero detectar si una frase empieza por “hola”. Todo lo que tendría que hacer es agregarle a la anterior expresión un ^. Quedaría de esta manera:

^hello

Con este simple cambio, ya la expresión regular se comporta más como queremos. Podemos ir agregando cosillas hasta llegar a la expresión final, o podemos quedarnos con la expresión aproximada (que a veces funciona mejor, ya te lo explico).

Ahora surgen dos dudas:

  1. Por qué usar un RegEx y no usar un simple startswith (de python)
  2. ¿Cómo funciona esto por dentro?

Voy a responder ambas preguntas en un mismo argumento. Hay dos razones por las que usar expresiones regulares es preferible a startswith. La primera, más obvia, es que regex es un caso general. Con ellas podemos crear patrones loquísimos (que ya veremos).

La segunda, el tiempo: mientras que en Python tenemos que leer línea por línea y para aplicarle startswith, con regex lo podemos lograr para todo el texto en una sola sentencia. Entonces, por ese lado, RegEx wins.

Trascendencia de las expresiones regulares: ¿por qué son importantes?

Ahora, mencioné que RegEx era un caso general, ¿verdad? Un RegEx puede ser expresado en forma de máquina de estados y eso cambia totalmente el juego.

Las máquinas de estado son la cosa más increíble que tenemos como humanidad, pero no quiero nerdear sobre máquinas de estados (por hoy), quiero nerdear sobre RegEx. ¿Recuerdan el RegEx ‘^hola’? Ese RegEx lo podemos representar como la siguiente máquina:

state_machine.png

Si miramos con estos ojos a las expresiones regulares, estoy muy seguro de que lo vas a entender mejor. ¿Hasta dónde llega esto? Bueno, les presento a este tipo, que en su video nos enseña cómo gastar 9.5k USD en AWS… Digo, resolver Pokemon con una sola expresión regular. No tiene desperdicio.

Lo que me lleva a preguntarme, ¿es posible expresar toda la computación a partir de expresiones regulares? La respuesta es… No tengo la menor idea. Un grupo de personas estamos intentando extender RegEx a Turing completo, pero hay mucha discusión sobre si YA es Turing completo. Dejo esto sobre la mesa y paso a otro tema porque caso contrario no avanzaremos.

Volviendo a las RegEx

Dejaré por aquí una tabla de trucos para las expresiones regulares. Si vas poco a poco generando máquinas de estado más complejas, acabarás por entender todo y volverte un RegEX master, pero aquí vamos con algunas, las más útiles e interesantes.

cheat_sheet.png

¡Quiero más ejemplos de RegEx!

Vamos por un ejemplo sencillo: vamos a identificar correos electrónicos

  1. Primero intentemos detectar todo, según mi tablita de códigos, punto (.) equivale a cualquier carácter, empezamos por ahí:
.
  1. Listo, es un poco sencillo, pero funciona. Todos los correos tienen @ así que, ¿por qué nuestro regex no iba a tener uno? Si lo acomodamos, queda así:
.@.
  1. Esto detecta el arroba y los dos caracteres junto a él, vamos progresando. Ahora quiero que detecte todos los caracteres que hay junto al arroba. Si miro mi tablita de códigos me doy cuenta de que hay algo que dice 1 o más, a ver si me sirve:
.+@.+
  1. Súper, ya se ve mucho mejor. Vamos por el punto del .com. Hay un problema y es que el caracter de punto representa cualquier caracter. Entonces, ¿cómo digo que necesito específicamente un punto? Lo escapo con ‘\’:
.+@.+\..
  1. Ahora, el dominio. Vamos a cortarlo, no queremos un dominio de más de 3 caracteres. Podemos cortarlo con las llaves {n,m}, eso nos da un rango máximo y un rango mínimo. Quedaría así.
.+@.+\..{2,3}
  1. Hay algo curioso y es que hay muchos más casos, subdominios, no queremos espacios, caracteres especiales (excepto por algunas excepciones), entre otros. Además, no hemos hablado de IPs. Vamos, un lío completo. Lo más importante de todo es saber cuándo parar. Podemos acabar con esto:
(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

Este es un RegEx para correos electrónicos que funciona en el 99.99% de los casos, pero no es ni usable, ni mantenible, ni nada.

Más ejemplos: vamos a hacer el chatbot más soso de la vida

Esto nos servirá para entender el tema de los reemplazos, uno de los usos más interesantes de RegEx. Imaginemos que yo saludo a mi bot y le digo, “Hola, soy Hector”. Esto lo puedes probar en cualquier editor de RegEx, como Visual studio code o algún otro IDE.

  1. Quiero hacer match, así que mi regex va a ser algo como:
Hola, soy .+
  1. Esto hará que, sea cual sea mi nombre, sea detectado. Pero hay algo más interesante. Si yo hago un agrupamiento del nombre, es decir le pongo paréntesis, así:
Hola, soy (.+)
  1. Entonces pasan cosas interesantes, como que esa información que está entre paréntesis se mueve al replace, usando $1. Es decir, si yo pongo en el replace: $1 “Hola, soy Hector”, se va a remplazar con “Hector” entonces, si yo cambio el replace por
Mucho gusto $1 ¿Cómo te va?

Entonces el bot va a responder Mucho gusto Hector ¿Cómo te va? ¡y ya tenemos un bot que nos saluda!
Podemos tener tantos agrupamientos como queramos y podemos incluso ponerles nombre, pero eso ya está en la guía de trucos.

Último ejemplo: webscraping ultra rápido

Una última para los colegas de Data Science. Usualmente para web scraping usamos librerías como Beautifulsoup, pero con RegEx puedes sacar información mucho más rápido de una página html simplemente con esta sentencia, con la que podemos extraer el título de un blogpost o una noticia:

<h1.+>(.+)</h1>

El mejor truco para aprender expresiones regulares

Practica. En este artículo no hemos visto aún todas las peculiaridades de RegEx, pero ya tienes lo más importante: curiosidad e intuición para seguir aprendiendo por tu cuenta. Aquí en Platzi tenemos el mejor Curso de Expresiones Regulares de todos. ¡Ve a verlo y nunca pares de escribir expresiones regulares!

Hector
Hector
hector_pulido_

29077Puntos

hace 3 años

Todas sus entradas
Escribe tu comentario
+ 2
Ordenar por:
6
59633Puntos

Oh, wow, qué artículo tan interesante.
No estoy en el mundo del desarrollo y la programación, pero cada vez que leo las bondades de saber sobre él me quedo con mucha curiosidad y admiración. Felicidades por el post. 😉

1
29077Puntos
3 años

¡Que bien que te haya parecido interesante!, no necesitas estar en el mundo de desarrollo para usar regex 🙌 puedes usarlas incluso en Excel o cuando estes buscando en un documento

5
32945Puntos

Magnifico Post, sucinto, pero con un grado de profundidad que deja deseando más cursos como el del profe que dicta Expresiones regulares, gracias Hector!

3
6977Puntos

Que agradable lectura de un tema que no manejo… Muy buen post. Tomaré el curso 🙋‍♂️

3
29787Puntos

Magistral, jamás se me había ocurrido ese uso para web scrapping, esta increíble

3
29077Puntos
3 años

Y es solo la punta del iceberg, imaginate pasar de xml a json, o de csv a sql 👀

3
23048Puntos

Brillante! Que contenido mas entretenido y constructivo!
Por favor un post de Maquinas de Estado!!
Gracias!

2
29077Puntos
3 años

Va a la lista de proximos posts entonces 😁

2
3953Puntos

Me gusta pero me asusta!

2
29077Puntos
2 años

Jajaja es como un perro grande, da un poco de miedo, pero luego te das cuenta de que es un amor. 😆

– Hector que pedo con tus analogías 🤭 –

2
9784Puntos

Muy buen artículo Pulido, no conocía todo el alcance que RegEx podría tener

1
29077Puntos
3 años

Y eso es apenas lo mas basico 👀 😲

2
14607Puntos

Excelente post Héctor, quede con ganas de más en web scrapping

1
29077Puntos
3 años

Jajaja fue solo un pequeño abrebocas, lo mejor esta en el curso 😆