Cheat Sheet de Python

Expresiones Regulares (RegEx)

¿Qué son las RegEx?

Una secuencia de caracteres que define un patrón de búsqueda. Son como un "super buscador" para encontrar, validar y reemplazar texto.

El Módulo re

Python proporciona el módulo `re` en su librería estándar para trabajar con expresiones regulares.

import re

Metacaracteres Básicos

Son caracteres especiales que tienen un significado en el patrón.

.   Cualquier carácter (excepto salto de línea)
^   Inicio de la cadena
$   Fin de la cadena
[]  Un conjunto de caracteres permitidos
|   Operador OR (uno u otro)
()  Agrupar expresiones

Ejemplo de Metacaracteres

Encontrar palabras que empiezan con 'c' y terminan con 'o'.

patron = r"^c.*o$"
# 'c' al inicio, seguido de cualquier cosa (.*), y 'o' al final.

re.match(patron, "cielo") # Coincide
re.match(patron, "carro") # Coincide
re.match(patron, "moto")  # No coincide

Clases de Caracteres

Secuencias especiales que representan conjuntos comunes.

\d  Cualquier dígito (0-9)
\D  Cualquier NO dígito
\w  Cualquier carácter alfanumérico (a-z, A-Z, 0-9, _)
\W  Cualquier NO alfanumérico
\s  Cualquier espacio en blanco (espacio, tab, newline)
\S  Cualquier NO espacio en blanco

Conjuntos Personalizados: []

Permiten definir tus propias clases de caracteres.

[aeiou]  # Cualquier vocal minúscula
[a-z]    # Cualquier letra minúscula
[A-Z0-9] # Cualquier letra mayúscula o dígito
[^0-9]   # Cualquier carácter que NO sea un dígito

Cuantificadores

Indican cuántas veces debe aparecer el carácter o grupo anterior.

*   0 o más veces
+   1 o más veces
?   0 o 1 vez
{n} Exactamente n veces
{n,} n o más veces
{n,m} Entre n y m veces

Ejemplo de Cuantificadores

Validar un código postal de 5 dígitos.

patron = r"^\d{5}$"
# Inicio, 5 dígitos exactamente, y fin.

re.match(patron, "28080") # Coincide
re.match(patron, "2808")  # No coincide
re.match(patron, "280801") # No coincide

Función: re.search()

Busca la primera aparición del patrón en cualquier parte de la cadena. Devuelve un objeto `Match` si lo encuentra, o `None` si no.

texto = "Hola 123 Mundo"
match = re.search(r"\d+", texto)

if match:
    print(f"Encontrado: {match.group(0)}") # '123'

Función: re.match()

Similar a `search()`, pero solo busca coincidencias al principio de la cadena.

texto = "123 Hola"
# re.match(r"Hola", texto) -> No coincide

texto2 = "Hola 123"
# re.match(r"Hola", texto2) -> Sí coincide

Función: re.findall()

Devuelve una lista con todas las coincidencias del patrón en la cadena.

texto = "Email1: test@test.com, Email2: admin@web.es"
emails = re.findall(r"\w+@\w+\.\w+", texto)
print(emails)
# ['test@test.com', 'admin@web.es']

Función: re.sub()

Busca todas las apariciones de un patrón y las sustituye por otra cadena.

texto = "Mi teléfono es 123-456-789"
# Ocultar los números
texto_oculto = re.sub(r"\d", "*", texto)
print(texto_oculto) # Mi teléfono es ***-***-***

Grupos de Captura: ()

Los paréntesis permiten "capturar" partes específicas de la coincidencia para usarlas después.

texto = "Juan Perez"
# Captura el nombre y el apellido en grupos separados
patron = r"(\w+)\s(\w+)"
match = re.search(patron, texto)

print(match.group(0)) # 'Juan Perez' (coincidencia completa)
print(match.group(1)) # 'Juan' (primer grupo)
print(match.group(2)) # 'Perez' (segundo grupo)

Uso de Grupos con re.sub()

Puedes referenciar los grupos capturados en la cadena de reemplazo con `\1`, `\2`, etc.

# Cambiar el formato de una fecha
fecha = "2024-11-25"
# Captura año, mes y día
patron = r"(\d{4})-(\d{2})-(\d{2})"
# Reordena los grupos
nueva_fecha = re.sub(patron, r"\2/\3/\1", fecha)
print(nueva_fecha) # "11/25/2024"

Compilar Patrones: re.compile()

Si vas a usar el mismo patrón muchas veces, es más eficiente compilarlo primero. Crea un objeto de patrón reutilizable.

patron_email = re.compile(r"\w+@\w+\.\w+")

# Ahora puedes usar el objeto compilado
emails1 = patron_email.findall(texto1)
emails2 = patron_email.findall(texto2)

Modificadores (Flags)

Permiten cambiar el comportamiento de la expresión regular.

# re.IGNORECASE o re.I: Ignora mayúsculas/minúsculas
# re.MULTILINE o re.M: Hace que ^ y $ funcionen al inicio/final de cada línea
# re.DOTALL o re.S: Hace que '.' coincida también con saltos de línea

re.search("hola", "Hola Mundo", flags=re.IGNORECASE)

Cadenas Raw: `r""`

Es una **muy buena práctica** usar siempre cadenas "raw" (crudas) para los patrones de RegEx. Evita que Python interprete los `\` como secuencias de escape.

# Bien
patron = r"\d+"

# Mal (propenso a errores)
patron = "\\d+"

Caso de Uso: Validación

Comprobar si un email tiene un formato válido.

def es_email_valido(email):
    patron = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
    return re.match(patron, email) is not None

print(es_email_valido("test@web.com")) # True
print(es_email_valido("test@web"))     # False

Conclusión

Las expresiones regulares son una herramienta increíblemente densa pero potente. Dominarlas te da un superpoder para cualquier tarea de manipulación de texto.