Expresiones regulares en python



@eduardo_gpg

Número de visitas 7065

Tiempo de lectura 5 min

5 Julio 2020

Las expresiones regulares, también conocidas como regex, podemos definirlas como patrones de textos a través de los cuales podemos establecer la estructura que debe poser una cadena de texto.

Cómo puedes imaginarte las expresiones regulares juegan un papel de suma importancia en el mundo del desarrollo. Son algo que, desde mi punto de vista, todos los programadores debemos conocer.

Me atrevo a decir que el tema de expresiones regulares es sin duda uno de los temas más extensos y complejos con el cual uno puede llegar a toparse. Decenas, si no cientos de libros se han escritos de ello; e intentar resumir todo el contenido en un post o en un vídeo sin duda sería una tarea titánica. Es por ello que preparé esta pequeña serie de posts donde daremos nuestros primeros pasos con las expresiones regulares mediante el lenguaje de programación Python. 🐍

Nota: Para que puedas seguir esta serie de tutoriales solo debes tener conocimientos de strings en Python, Qué son y por supuesto cómo funcionan.

Bien, sin más que decir, no perdamos más el tiempo y comencemos.

Expresiones regulares

Cómo mencionamos anteriormente las expresiones regulares nos permiten definir el formato/estructura que debe poseer una cadena de texto. Utilizando expresiones regulares es posibles validar patrones, buscar y extraer elementos de una cadenas, así como reemplazar porciones texto o dividir grandes cadenas en fragmentos más pequeños.

Por ejemplo, imaginemos el siguiente escenario.

Nos encontramos desarrollando un página web y se nos pide implementar el feature de alta de usuarios. Para ello sin duda debemos trabajar con un formulario. De igual forma se nos pide que el input para el correo electrónico solo debe permitir correos electrónicos válidos. En primera instancia podemos pensar que, implementando una pequeña condición llegaremos a la solución deseada; basta con validar que el arroba (@) y el punto (.) existan en la cadena, ¿no? 🧐

El código pudiera quedar de la siguiente manera.

if '@' in input and '.' in input:
    print('Correo electrónico valido')

Esto funciona para ejemplos muy sencillos, pero, ¿Qué pasa si un usuario (De forma maliciosa o no) introduce una cadena de texto que no sea un correo electrónico, pero que sí cumpla con las condiciones?

.@pywombatExample!!!!

Tener condiciones para cada uno de los posibles escenarios no es para nada viable. Para estos casos lo mejor que podemos hacer es apoyarnos de una expresión regular.

Tip: ¿Sabes cuál es la diferencia entre una expresión y una sentencia? ¿No? Aquí te comparto un Post que te puede interesar.

Expresiones en Python

Para nosotros podemos implementar expresiones regulares en Python haremos uso del módulo re. Este módulo se encuentra dentro de la biblioteca estándar de Python, así que no hay necesidad de instalar absolutamente nada; basta con importar y listo.

>>> import re

Una vez la librería haya sido importada ya podremos compilar nuestros patrones. Compilar un patrón es un paso de suma importancia, ya que con él seremos capaces de implementar nuestras expresiones sobre la n cantidad de strings que deseemos.

Comencemos con algo sencillo. Conozcamos si la palabra PyWombat existe como tal dentro de una oración.

>>> pattern = re.compile(r'\bPyWombat\b')

Utilizando el método match seremos capaces de conocer si existen coincidencias para un patrón al comienzo de una cadena.

>>> pattern.match("PyWombat demo")   
<re.Match object; span=(0, 8), match='PyWombat'>

Al nosotros ejecutar el ejemplo anterior, obtendremos como resultado un objeto de tipo re.Match, con lo cual confirmamos que el string cumple con la expresión regular.


pff, para este sencillo ejemplo creo hay mucho que explicar. Veamos.

Comencemos con el Raw String Notation (r'texto') una forma en la cual Python nos permite implementar expresiones regulares. Para utilizar el Raw String Notation debemos anteponer el carácter r a nuestro string; esto nos permitirá utilizar los backslashes \ como caracteres normales.

Aquí un par de ejemplos.

Si recordamos la función print nos permite imprimir en consola la n cantidad de strings qué deseemos, basta con colocar estos strings como argumentos. En la impresión los strings serán separados mediante un espacio en blanco.

>>> print('Hola mundo', 'desde PyWombat')
Hola mundo desde PyWombat

Hasta aquí nada nuevo, sin embargo ¿Qué pasa si en el segundo argumento colocamos \b?

>>> print('Hola mundo', '\bdesde PyWombat')
Hola mundodesde PyWombat

En este caso al utilizar \b le indicamos a Python que deseamos retroceder un carácter en la impresión, quedando así una salida muy poco convencional: Hola mundodesde PyWombat

Si utilizamos el Raw String Notation, \ y b serán tomados como simples caracteres, y podrán ser visualizados en consola.

>>> print('Hola mundo', r'\bdesde PyWombat')                                                
Hola mundo \bdesde PyWombat

Veamos otro ejemplo para que nos quede más en claro. En este caso con un salto de línea.

 >>> print('\nMensaje con salto de línea', r'\nmensaje sin salto de línea')                  

Mensaje con salto de línea \nmensaje sin salto de línea

Al utilizar el Raw String Notation el salto de línea no se da, y \n es tomado como parte del string.

He aquí la importancia de utilizar un Raw String Notation, a partir de él seremos capaces de utilizar le backslash sin ningún problema. 🥳

Otra forma de implementar el backslash es mediante un doble backslash. Aun que de forma personal recomiendo el Raw String Notation.

print('\\n') 

Ok, creo que el punto quedo claro, ahora examinemos la expresión utilizada: \bPyWombat\b.

Para ello debemos explicar cómo se estructura una expresión regular.

Sintaxis

La sintaxis de una expresión regular se conforma de caracteres ordinarios junto con caracteres especiales. Los caracteres ordinarios pueden ser letras de la a a la z así como números del 0 al 9. Por otro lado, los caracteres especiales (También conocidos como metacaracteres) serán los encargados de definir los patrones dentro del string.

En una expresión regular existen doce metacaracteres los cuales podemos utilizar.

  • Backslash \
  • Negación ^
  • Signo de dolar $
  • Punto .
  • Pipe |
  • Signo de interrogación ?
  • Asterisco *
  • Suma +
  • paréntesis apertura (
  • Paréntesis cierre )
  • Corchete apertura [
  • Corchete cierre ]
  • Llave apertura {

Para nuestro ejemplo \bPyWombat\b encontraremos tanto caracteres ordinarios como metacaracteres. En este casos los caracteres ordinarios serán todos los caracteres que conforman la palabra PyWombat, por otro lado los metacaracteres serán el doble \b.

Según Wikipedia el metacarácter \b: Marca la posición de una palabra limitada por espacios en blanco, puntuación o el inicio/final de una cadena.

🐍 Al metacarácter \b también podemos conocerlo como word boundary.

Para nuestro ejemplo estamos buscando la palabra PyWombat dentro de una oración. PyWombat puede comenzar oración o finalizar la oración, puede, de igual manera, preceder o ser precedido por un espacio en blanco o signo de puntuación. Vaya, estamos buscando la palabra per se.

Si PyWombat fuera parte de una palabra, ya sea que se encuentre al inicio, en el centro o al final, la expresión regular no se cumpliría.

>>> pattern = re.compile(r'\bPyWombat\b')   
>>> pattern.match("PyWombatHola")
# Sin resultado

>>> pattern.match("HolaPyWombatMundo") 
# Sin resultado

>>> pattern.match("HolaPyWombat") 
# Sin resultado

🐍 Me gustaría compartir contigo un link donde podrás encontrar, de forma mucho más detallada, patrones y combinaciones que podemos utilizar en nuestras expresiones regulares.

Búsqueda por patrones

Otra forma de conocer si un patrón existe dentro de una cadena, es mediante el método search. A diferencia del método match, donde se busca un coincidencia al inicio, con el método search la búsqueda se realiza sobre cualquier parte del string.

>>> pattern = re.compile(r'\bPyWombat\b')
>>> pattern.search("Hola mundo desde PyWombat")
<re.Match object; span=(17, 25), match='PyWombat'>

Aquí un par de ejemplos más.

>>> pattern = re.compile(r'\bPy\b') 
>>> pattern.search("Hola mundo desde PyWombat") 
# Sin resultados

>>> pattern.search("Archivo con extensión .Py") 
<re.Match object; span=(23, 25), match='Py'>
>>> pattern = re.compile(r'\bPy')
>>> pattern.search("Hola mundo desde PyWombat") 
<re.Match object; span=(17, 19), match='Py'>
>>> pattern = re.compile(r'at\b') 
>>> pattern.search("Hola mundo desde PyWombat") 
<re.Match object; span=(23, 25), match='at'>

Conclusión

Listo, ya sabemos implementar expresiones regulares con Python, o bueno, por lo menos una muy sencilla. En este post nos apoyamos del metacarácter \b (“word boundary”) para conocer si una palabra existe o no dentro de una oración.

Si bien es cierto en la primera sección hablamos de validar correos electrónicos mediante expresiones regulares, creo que para llegar a ese ejemplo aun nos hace falta camino por recorrer. Por ello no te debes perder los siguientes post y vídeos de la serie. 😋

De igual forma te comparto un listado de patrones con los cuales puedes practicar.

Siguiente entregas


¿El contenido te resulto de ayuda?

Para poder dejar tu opinión es necesario ser un usuario autenticado. Login