Python
Tutorial Python: Módulo re
Aprende a usar el módulo re en Python para crear, buscar y manipular expresiones regulares con ejemplos prácticos y técnicas avanzadas.
Aprende Python y certifícatePatrones básicos
Las expresiones regulares (o regex) son secuencias de caracteres que forman un patrón de búsqueda, principalmente utilizadas para operaciones de búsqueda y manipulación de texto. En Python, el módulo re proporciona todas las herramientas necesarias para trabajar con estas expresiones.
Un patrón básico es simplemente una secuencia de caracteres que se busca exactamente como está escrita. Por ejemplo, si buscamos el patrón "python" en un texto, encontraremos todas las ocurrencias exactas de esa palabra.
Caracteres literales
La forma más simple de una expresión regular es una secuencia de caracteres literales que coinciden exactamente con el texto buscado:
import re
texto = "Python es un lenguaje de programación versátil y potente."
resultado = re.search("Python", texto)
if resultado:
print(f"Encontrado: {resultado.group()}")
print(f"Posición: {resultado.start()}-{resultado.end()}")
En este ejemplo, buscamos la palabra "Python" en el texto. La función search()
devuelve un objeto match si encuentra el patrón, o None
si no lo encuentra. El método group()
devuelve el texto coincidente, mientras que start()
y end()
indican las posiciones de inicio y fin.
Patrones de caracteres simples
Podemos buscar cualquier carácter de un conjunto utilizando corchetes []
:
import re
texto = "El teléfono de Ana es 555-123-456 y el de Juan es 555-789-012"
patron = "[0-9]" # Busca cualquier dígito
# Encontrar todas las coincidencias
coincidencias = re.findall(patron, texto)
print(coincidencias) # Imprime todos los dígitos encontrados
Este patrón [0-9]
coincide con cualquier dígito del 0 al 9. La función findall()
devuelve una lista con todas las coincidencias encontradas.
Clases de caracteres predefinidas
El módulo re proporciona algunas clases de caracteres predefinidas que facilitan la creación de patrones comunes:
\d
- Coincide con cualquier dígito (equivalente a[0-9]
)\D
- Coincide con cualquier carácter que no sea un dígito\w
- Coincide con cualquier carácter alfanumérico o guion bajo (equivalente a[a-zA-Z0-9_]
)\W
- Coincide con cualquier carácter que no sea alfanumérico\s
- Coincide con cualquier espacio en blanco (espacio, tabulación, salto de línea)\S
- Coincide con cualquier carácter que no sea un espacio en blanco
import re
texto = "Python 3.11 fue lanzado en 2022."
# Encontrar todos los dígitos
digitos = re.findall(r"\d", texto)
print("Dígitos:", digitos)
# Encontrar todas las palabras
palabras = re.findall(r"\w+", texto) # El + indica "uno o más"
print("Palabras:", palabras)
Nota el uso de r
antes de las cadenas de patrones. Esto crea una cadena raw (cruda) que evita que Python interprete las secuencias de escape como \d
o \w
.
Anclas y límites
Las anclas son caracteres especiales que indican posiciones específicas en el texto:
^
- Coincide con el inicio de una línea$
- Coincide con el final de una línea\b
- Coincide con un límite de palabra\B
- Coincide con cualquier posición que no sea un límite de palabra
import re
texto = "Python es genial. python es fácil de aprender."
# Buscar 'Python' solo al inicio de una línea
inicio_linea = re.findall(r"^Python", texto)
print("Al inicio:", inicio_linea) # Encuentra 'Python'
# Buscar 'Python' sin importar mayúsculas/minúsculas
todas = re.findall(r"python", texto, re.IGNORECASE)
print("Todas:", todas) # Encuentra ambas ocurrencias
# Buscar 'Python' como palabra completa
palabras_completas = re.findall(r"\bPython\b", texto, re.IGNORECASE)
print("Palabras completas:", palabras_completas)
El flag re.IGNORECASE
(o re.I
) hace que la búsqueda sea insensible a mayúsculas y minúsculas.
Patrones para validación básica
Las expresiones regulares son muy útiles para validar formatos comunes como correos electrónicos, números de teléfono o códigos postales:
import re
# Validar un correo electrónico simple
def validar_email(email):
patron = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
return bool(re.match(patron, email))
# Validar un número de teléfono español (9 dígitos)
def validar_telefono(telefono):
patron = r"^\d{9}$"
return bool(re.match(patron, telefono))
# Ejemplos
emails = ["usuario@dominio.com", "nombre.apellido@empresa.es", "invalido@.com"]
for email in emails:
print(f"{email}: {'✓' if validar_email(email) else '✗'}")
telefonos = ["912345678", "600123456", "12345"]
for telefono in telefonos:
print(f"{telefono}: {'✓' if validar_telefono(telefono) else '✗'}")
Extracción de información con patrones básicos
Podemos usar patrones para extraer información específica de textos:
import re
# Extraer fechas en formato DD/MM/AAAA
texto = "La reunión será el 15/06/2023 y la entrega está prevista para el 30/09/2023."
patron_fecha = r"\d{2}/\d{2}/\d{4}"
fechas = re.findall(patron_fecha, texto)
print("Fechas encontradas:", fechas)
# Extraer códigos de producto (formato: ABC-12345)
inventario = "Productos disponibles: ABC-12345, XYZ-98765, DEF-54321"
patron_producto = r"[A-Z]{3}-\d{5}"
productos = re.findall(patron_producto, inventario)
print("Códigos de producto:", productos)
Búsqueda y reemplazo básico
La función sub()
permite reemplazar texto que coincide con un patrón:
import re
# Censurar números de teléfono
texto = "Contacta con Juan en el 912345678 o con Ana en el 600123456"
texto_censurado = re.sub(r"\d{9}", "XXX-XXX-XXX", texto)
print(texto_censurado)
# Formatear números de teléfono
def formatear_telefono(match):
num = match.group(0) # El texto completo que coincidió
return f"{num[:3]}-{num[3:6]}-{num[6:]}"
texto_formateado = re.sub(r"\d{9}", formatear_telefono, texto)
print(texto_formateado)
Uso de patrones en análisis de logs
Las expresiones regulares son muy útiles para analizar archivos de registro:
import re
log = """
2023-06-15 08:30:45 INFO: Aplicación iniciada
2023-06-15 08:31:23 WARNING: Conexión lenta detectada
2023-06-15 08:32:10 ERROR: No se pudo conectar a la base de datos
2023-06-15 08:35:42 INFO: Conexión restablecida
"""
# Extraer todas las entradas de error
errores = re.findall(r".*ERROR.*", log)
print("Errores encontrados:")
for error in errores:
print(f" - {error.strip()}")
# Extraer fecha, hora y tipo de mensaje
patron_log = r"(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) (\w+): (.+)"
for linea in log.strip().split('\n'):
match = re.match(patron_log, linea)
if match:
fecha, hora, tipo, mensaje = match.groups()
if tipo == "WARNING" or tipo == "ERROR":
print(f"Alerta [{tipo}] - {fecha} {hora}: {mensaje}")
Los patrones básicos de expresiones regulares son fundamentales para realizar operaciones de búsqueda y manipulación de texto en Python. Aunque pueden parecer complejos al principio, con práctica se convierten en una herramienta indispensable para el procesamiento de texto.
Metacaracteres y cuantificadores
Los metacaracteres y cuantificadores son elementos fundamentales que amplían considerablemente el poder de las expresiones regulares, permitiéndonos crear patrones más flexibles y precisos. Mientras que los patrones básicos nos permiten buscar coincidencias exactas, estos componentes avanzados nos dan la capacidad de definir patrones con variaciones y repeticiones.
Metacaracteres principales
Los metacaracteres son caracteres con significados especiales dentro de una expresión regular:
.
- Coincide con cualquier carácter excepto saltos de línea^
- Coincide con el inicio de una cadena o línea$
- Coincide con el final de una cadena o línea|
- Funciona como operador OR lógico entre patrones()
- Agrupa expresiones y captura coincidencias[]
- Define un conjunto de caracteres\
- Escapa metacaracteres o introduce secuencias especiales
Veamos ejemplos prácticos de cómo utilizar estos metacaracteres:
import re
texto = "El precio es 23.50 euros y el código es ABC-123"
# El punto coincide con cualquier carácter
resultados = re.findall(r"c.d", texto)
print(f"Patrones 'c.d': {resultados}") # Encuentra 'cód'
# Alternancia con el operador |
colores = "rojo verde azul amarillo"
resultados = re.findall(r"rojo|azul", colores)
print(f"Colores (rojo o azul): {resultados}") # Encuentra 'rojo' y 'azul'
# Escapar metacaracteres para buscarlos literalmente
texto_puntos = "¿Cómo funciona esto...? No lo sé."
resultados = re.findall(r"\.\.\.", texto_puntos)
print(f"Puntos suspensivos: {resultados}") # Encuentra '...'
Cuantificadores
Los cuantificadores especifican cuántas veces debe aparecer un elemento en el patrón:
*
- Cero o más repeticiones (0+)+
- Una o más repeticiones (1+)?
- Cero o una repetición (opcional){n}
- Exactamente n repeticiones{n,}
- Al menos n repeticiones{n,m}
- Entre n y m repeticiones (inclusive)
Estos cuantificadores se aplican al elemento inmediatamente anterior, que puede ser un carácter, un grupo o una clase de caracteres:
import re
texto = "Teléfonos: 912345678, 91-234-56-78, 912-34-56-78 y 91 234 56 78"
# Buscar números de teléfono con diferentes formatos
patron = r"\d{2}[\s-]?\d{3}[\s-]?\d{2}[\s-]?\d{2}"
telefonos = re.findall(patron, texto)
print(f"Teléfonos encontrados: {telefonos}")
# Buscar palabras que empiecen con 'p' y tengan al menos 5 letras
texto = "Python es un programa potente para programación"
palabras_p = re.findall(r"\bp\w{4,}\b", texto, re.IGNORECASE)
print(f"Palabras con 'p' de 5+ letras: {palabras_p}") # Encuentra 'Python', 'potente', 'programación'
Comportamiento voraz vs. no voraz
Por defecto, los cuantificadores son voraces (greedy), lo que significa que intentan coincidir con la mayor cantidad posible de caracteres. Podemos hacerlos no voraces (non-greedy o lazy) añadiendo un ?
después del cuantificador:
import re
html = "<div>Primer contenido</div><div>Segundo contenido</div>"
# Cuantificador voraz (comportamiento predeterminado)
patron_voraz = r"<div>.*</div>"
resultado_voraz = re.findall(patron_voraz, html)
print(f"Coincidencia voraz: {resultado_voraz}") # Captura todo desde el primer <div> hasta el último </div>
# Cuantificador no voraz
patron_no_voraz = r"<div>.*?</div>"
resultado_no_voraz = re.findall(patron_no_voraz, html)
print(f"Coincidencias no voraces: {resultado_no_voraz}") # Captura cada <div> por separado
Combinación de metacaracteres y cuantificadores
La verdadera potencia de las expresiones regulares surge al combinar metacaracteres y cuantificadores:
import re
# Validar una dirección IPv4
def validar_ipv4(ip):
# Patrón para un octeto: número entre 0 y 255
octeto = r"(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)"
patron = f"^{octeto}\.{octeto}\.{octeto}\.{octeto}$"
return bool(re.match(patron, ip))
# Probar algunas direcciones IP
ips = ["192.168.1.1", "10.0.0.1", "256.0.0.1", "192.168.1", "a.b.c.d"]
for ip in ips:
print(f"{ip}: {'✓' if validar_ipv4(ip) else '✗'}")
En este ejemplo, construimos un patrón complejo para validar direcciones IPv4. Cada octeto debe ser un número entre 0 y 255, lo que requiere combinar alternancia (|
), agrupación (()
) y cuantificadores específicos.
Patrones para análisis de texto
Los metacaracteres y cuantificadores son especialmente útiles para analizar textos estructurados:
import re
# Analizar un archivo de configuración simple
config = """
# Configuración del servidor
puerto = 8080
host = 192.168.1.10
timeout = 30s
max_conexiones = 100
"""
# Extraer pares clave-valor
patron = r"^(\w+)\s*=\s*(.+)$"
for linea in config.splitlines():
match = re.match(patron, linea)
if match:
clave, valor = match.groups()
print(f"Configuración: {clave} = {valor}")
# Extraer valores numéricos con unidades opcionales
patron_valor = r"(\d+)(\w*)"
for linea in config.splitlines():
if "=" in linea:
valor = linea.split("=")[1].strip()
match = re.match(patron_valor, valor)
if match:
numero, unidad = match.groups()
print(f"Valor numérico: {numero} {unidad if unidad else '(sin unidad)'}")
Validación de formatos comunes
Los metacaracteres y cuantificadores son esenciales para validar formatos comunes como URLs, correos electrónicos o fechas:
import re
# Validar URL
def validar_url(url):
patron = r"^https?://(?:www\.)?[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+(/[a-zA-Z0-9-._~:/?#[\]@!$&'()*+,;=]*)?$"
return bool(re.match(patron, url))
# Validar fecha en formato DD/MM/AAAA
def validar_fecha(fecha):
patron = r"^(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[0-2])/\d{4}$"
if not re.match(patron, fecha):
return False
# Verificación adicional para fechas válidas
dia, mes, año = map(int, fecha.split('/'))
if mes in [4, 6, 9, 11] and dia > 30:
return False
if mes == 2:
es_bisiesto = (año % 4 == 0 and año % 100 != 0) or (año % 400 == 0)
if (es_bisiesto and dia > 29) or (not es_bisiesto and dia > 28):
return False
return True
# Ejemplos
urls = ["https://www.ejemplo.com", "http://ejemplo.com/ruta", "ftp://ejemplo.com"]
for url in urls:
print(f"{url}: {'✓' if validar_url(url) else '✗'}")
fechas = ["31/01/2023", "29/02/2024", "29/02/2023", "31/04/2023"]
for fecha in fechas:
print(f"{fecha}: {'✓' if validar_fecha(fecha) else '✗'}")
Extracción de información estructurada
Podemos usar metacaracteres y cuantificadores para extraer información estructurada de textos:
import re
# Extraer información de un log de servidor web
log_line = '192.168.1.10 - - [25/May/2023:10:15:32 +0200] "GET /index.html HTTP/1.1" 200 1234'
patron_log = r'(\d+\.\d+\.\d+\.\d+) .+ \[(.+?)\] "(\w+) (.+?) HTTP/[\d.]+?" (\d+) (\d+)'
match = re.match(patron_log, log_line)
if match:
ip, fecha, metodo, ruta, codigo, tamaño = match.groups()
print(f"IP: {ip}")
print(f"Fecha: {fecha}")
print(f"Método: {metodo}")
print(f"Ruta: {ruta}")
print(f"Código de respuesta: {codigo}")
print(f"Tamaño: {tamaño} bytes")
Uso de flags con metacaracteres
Python permite modificar el comportamiento de las expresiones regulares mediante flags:
import re
texto = """Este es un texto
con múltiples líneas.
Python es genial.
python es fácil de aprender."""
# Sin el flag MULTILINE, ^ y $ coinciden con inicio y fin del texto completo
print("Sin MULTILINE:")
print(re.findall(r"^Python", texto)) # Solo encuentra 'Python' al inicio del texto
# Con MULTILINE, ^ y $ coinciden con inicio y fin de cada línea
print("\nCon MULTILINE:")
print(re.findall(r"^Python", texto, re.MULTILINE)) # Encuentra 'Python' al inicio de líneas
# Combinar flags
print("\nCon MULTILINE e IGNORECASE:")
print(re.findall(r"^python", texto, re.MULTILINE | re.IGNORECASE)) # Encuentra ambos 'Python'/'python'
# Flag DOTALL hace que '.' coincida también con saltos de línea
print("\nCon DOTALL:")
print(re.findall(r"es.*fácil", texto)) # No encuentra nada (hay saltos de línea entre 'es' y 'fácil')
print(re.findall(r"es.*fácil", texto, re.DOTALL)) # Encuentra desde 'es' hasta 'fácil' atravesando líneas
Los metacaracteres y cuantificadores transforman las expresiones regulares de simples herramientas de búsqueda a potentes instrumentos de análisis y validación de texto. Aunque requieren práctica para dominarlos, su flexibilidad los hace indispensables para cualquier tarea avanzada de procesamiento de texto en Python.
Grupos de captura
Los grupos de captura son una de las características más potentes de las expresiones regulares, ya que permiten extraer partes específicas del texto que coinciden con subpatrones dentro del patrón principal. En Python, estos grupos se crean mediante paréntesis ()
y nos permiten aislar y manipular fragmentos concretos de las coincidencias encontradas.
Fundamentos de los grupos de captura
Cuando encerramos una parte de una expresión regular entre paréntesis, creamos un grupo que no solo agrupa esos elementos sino que también "captura" el texto coincidente para su uso posterior:
import re
texto = "La fecha de hoy es 15/06/2023"
patron = r"(\d{2})/(\d{2})/(\d{4})"
resultado = re.search(patron, texto)
if resultado:
fecha_completa = resultado.group(0) # Toda la coincidencia
dia = resultado.group(1) # Primer grupo: día
mes = resultado.group(2) # Segundo grupo: mes
año = resultado.group(3) # Tercer grupo: año
print(f"Fecha completa: {fecha_completa}")
print(f"Día: {dia}, Mes: {mes}, Año: {año}")
En este ejemplo, cada componente de la fecha (día, mes y año) se captura en un grupo separado, lo que nos permite acceder a ellos individualmente mediante el método group()
.
Acceso a múltiples grupos
Cuando trabajamos con varios grupos de captura, podemos acceder a todos ellos de diferentes maneras:
import re
texto = "Contacto: Juan Pérez (juan.perez@ejemplo.com)"
patron = r"([A-Za-z\s]+) \(([^)]+)\)"
resultado = re.search(patron, texto)
if resultado:
# Acceder a grupos individuales
nombre = resultado.group(1)
email = resultado.group(2)
print(f"Nombre: {nombre}")
print(f"Email: {email}")
# Obtener todos los grupos como una tupla
todos_los_grupos = resultado.groups()
print(f"Todos los grupos: {todos_los_grupos}")
# Desempaquetar directamente
nombre_alt, email_alt = resultado.groups()
print(f"Nombre (desempaquetado): {nombre_alt}")
print(f"Email (desempaquetado): {email_alt}")
El método groups()
devuelve una tupla con todos los grupos capturados, lo que facilita su desempaquetado en variables individuales.
Grupos nombrados
Para mejorar la legibilidad y mantenimiento del código, podemos asignar nombres a los grupos de captura utilizando la sintaxis (?P<nombre>patrón)
:
import re
log_entrada = "2023-06-15 14:32:15 - ERROR - Fallo en el módulo de autenticación"
# Usando grupos nombrados
patron = r"(?P<fecha>\d{4}-\d{2}-\d{2}) (?P<hora>\d{2}:\d{2}:\d{2}) - (?P<nivel>\w+) - (?P<mensaje>.*)"
resultado = re.search(patron, log_entrada)
if resultado:
# Acceder por nombre
fecha = resultado.group("fecha")
hora = resultado.group("hora")
nivel = resultado.group("nivel")
mensaje = resultado.group("mensaje")
print(f"Fecha: {fecha}")
print(f"Hora: {hora}")
print(f"Nivel: {nivel}")
print(f"Mensaje: {mensaje}")
# También podemos obtener un diccionario con todos los grupos nombrados
datos = resultado.groupdict()
print(f"Diccionario de grupos: {datos}")
Los grupos nombrados hacen que el código sea más legible y mantenible, especialmente cuando trabajamos con patrones complejos que contienen muchos grupos.
Grupos no capturantes
En ocasiones, necesitamos agrupar elementos de un patrón sin capturar su contenido. Para esto usamos la sintaxis (?:patrón)
:
import re
texto = "El precio es 23.50 euros"
# Grupo capturante normal
patron_capturante = r"(\d+\.\d+) euros"
resultado = re.search(patron_capturante, texto)
print(f"Grupos capturados: {resultado.groups()}") # ('23.50',)
# Grupo no capturante
patron_no_capturante = r"(?:\d+\.\d+) euros"
resultado = re.search(patron_no_capturante, texto)
print(f"Grupos capturados: {resultado.groups()}") # ()
# Combinando grupos capturantes y no capturantes
patron_mixto = r"(\d+)(?:\.)(\d+) euros"
resultado = re.search(patron_mixto, texto)
print(f"Grupos capturados: {resultado.groups()}") # ('23', '50')
Los grupos no capturantes son útiles cuando necesitamos la funcionalidad de agrupación (como aplicar un cuantificador a varios elementos) pero no necesitamos extraer ese contenido específico.
Referencias hacia atrás (backreferences)
Una característica poderosa de los grupos de captura es la capacidad de hacer referencia a ellos dentro de la misma expresión regular mediante backreferences. Esto se hace con \número
o \g<nombre>
para grupos nombrados:
import re
# Encontrar palabras repetidas
texto = "Este es es un ejemplo de texto con palabras palabras repetidas."
# Usando referencia numérica
patron = r"\b(\w+)\s+\1\b"
palabras_repetidas = re.findall(patron, texto)
print(f"Palabras repetidas: {palabras_repetidas}") # ['es', 'palabras']
# Encontrar etiquetas HTML coincidentes
html = "<div><p>Contenido del párrafo</p></div><span>Otro texto</span>"
# Usando referencia numérica para asegurar que las etiquetas coincidan
patron_html = r"<(\w+)>.*?</\1>"
etiquetas = re.findall(patron_html, html)
print(f"Etiquetas encontradas: {etiquetas}") # ['p', 'span']
# Con grupos nombrados
patron_html_nombrado = r"<(?P<tag>\w+)>.*?</(?P=tag)>"
etiquetas = re.findall(patron_html_nombrado, html)
print(f"Etiquetas encontradas (grupos nombrados): {etiquetas}") # ['p', 'span']
Las referencias hacia atrás son extremadamente útiles para encontrar patrones que deben coincidir consigo mismos, como etiquetas HTML, comillas coincidentes o palabras repetidas.
Grupos en sustituciones
Los grupos de captura son especialmente útiles en operaciones de sustitución, donde podemos reorganizar o transformar el texto capturado:
import re
# Invertir el orden de nombre y apellido
nombres = ["García, Ana", "López, Carlos", "Martínez, Elena"]
for nombre in nombres:
# Capturamos apellido y nombre, y los reorganizamos en la sustitución
nombre_formateado = re.sub(r"(\w+), (\w+)", r"\2 \1", nombre)
print(f"Original: {nombre} -> Formateado: {nombre_formateado}")
# Formatear números de teléfono
telefonos = ["912345678", "611234567", "942123456"]
for telefono in telefonos:
# Dividimos el número en grupos y lo formateamos
telefono_formateado = re.sub(r"(\d{3})(\d{3})(\d{3})", r"\1-\2-\3", telefono)
print(f"Original: {telefono} -> Formateado: {telefono_formateado}")
En estos ejemplos, usamos \1
, \2
, etc., en la cadena de reemplazo para hacer referencia a los grupos capturados en el patrón original.
Grupos con funciones de sustitución
Podemos llevar las sustituciones un paso más allá combinando grupos de captura con funciones de reemplazo:
import re
# Convertir fechas de formato DD/MM/AAAA a AAAA-MM-DD
texto = "Fechas importantes: 15/06/2023, 22/07/2023 y 30/09/2023"
def convertir_formato_fecha(match):
dia = match.group(1)
mes = match.group(2)
año = match.group(3)
return f"{año}-{mes}-{dia}"
texto_convertido = re.sub(r"(\d{2})/(\d{2})/(\d{4})", convertir_formato_fecha, texto)
print(f"Texto convertido: {texto_convertido}")
# Convertir temperaturas de Celsius a Fahrenheit
texto_temp = "Temperaturas: 20°C en Madrid, 15°C en Barcelona, 25°C en Sevilla"
def celsius_a_fahrenheit(match):
celsius = int(match.group(1))
fahrenheit = celsius * 9/5 + 32
return f"{fahrenheit:.1f}°F"
texto_convertido = re.sub(r"(\d+)°C", celsius_a_fahrenheit, texto_temp)
print(f"Temperaturas convertidas: {texto_convertido}")
Esta técnica es extremadamente poderosa para transformaciones complejas, ya que podemos aplicar cualquier lógica de programación a los valores capturados.
Extracción de datos estructurados
Los grupos de captura son ideales para extraer datos estructurados de textos como logs, informes o documentos:
import re
# Extraer información de un registro de ventas
registro = """
Producto: Laptop XPS 13
Precio: 1299.99€
Cantidad: 3
Cliente: María González
Fecha: 15/06/2023
"""
# Definimos patrones para cada campo con grupos nombrados
patrones = {
"producto": r"Producto: (?P<valor>.*)",
"precio": r"Precio: (?P<valor>\d+\.\d+)€",
"cantidad": r"Cantidad: (?P<valor>\d+)",
"cliente": r"Cliente: (?P<valor>.*)",
"fecha": r"Fecha: (?P<valor>\d{2}/\d{2}/\d{4})"
}
# Extraemos cada campo
datos_venta = {}
for campo, patron in patrones.items():
match = re.search(patron, registro)
if match:
datos_venta[campo] = match.group("valor")
print("Datos extraídos:")
for campo, valor in datos_venta.items():
print(f" {campo.capitalize()}: {valor}")
# Calculamos el total
if "precio" in datos_venta and "cantidad" in datos_venta:
total = float(datos_venta["precio"]) * int(datos_venta["cantidad"])
print(f"Total de la venta: {total:.2f}€")
Este enfoque permite extraer y procesar datos de manera estructurada a partir de textos que siguen un formato específico pero no están en un formato de datos como JSON o CSV.
Anidación de grupos
Los grupos de captura pueden anidarse para manejar estructuras jerárquicas:
import re
# Analizar una expresión matemática simple
expresion = "(2 + 3) * (4 - 1)"
# Capturamos la expresión completa y cada paréntesis por separado
patron = r"\(([^()]+)\) *([*+/-]) *\(([^()]+)\)"
match = re.search(patron, expresion)
if match:
expr1 = match.group(1) # "2 + 3"
operador = match.group(2) # "*"
expr2 = match.group(3) # "4 - 1"
print(f"Primera expresión: {expr1}")
print(f"Operador: {operador}")
print(f"Segunda expresión: {expr2}")
# Podemos analizar más profundamente cada subexpresión
def evaluar_subexpresion(expr):
patron_sub = r"(\d+) *([+\-*/]) *(\d+)"
sub_match = re.search(patron_sub, expr)
if sub_match:
num1 = int(sub_match.group(1))
op = sub_match.group(2)
num2 = int(sub_match.group(3))
if op == '+': return num1 + num2
if op == '-': return num1 - num2
if op == '*': return num1 * num2
if op == '/': return num1 / num2
resultado1 = evaluar_subexpresion(expr1)
resultado2 = evaluar_subexpresion(expr2)
print(f"Resultado de {expr1} = {resultado1}")
print(f"Resultado de {expr2} = {resultado2}")
# Evaluamos la expresión completa
if operador == '+': resultado_final = resultado1 + resultado2
if operador == '-': resultado_final = resultado1 - resultado2
if operador == '*': resultado_final = resultado1 * resultado2
if operador == '/': resultado_final = resultado1 / resultado2
print(f"Resultado final: {expresion} = {resultado_final}")
La anidación de grupos permite descomponer problemas complejos en partes más manejables, facilitando el análisis de estructuras jerárquicas como expresiones matemáticas, código fuente o documentos estructurados.
Los grupos de captura son una herramienta fundamental para extraer y manipular información específica de textos mediante expresiones regulares. Dominando esta técnica, podemos realizar tareas avanzadas de procesamiento de texto con código conciso y eficiente.
Funciones de búsqueda y reemplazo
El módulo re de Python ofrece un conjunto completo de funciones para realizar operaciones de búsqueda y reemplazo en textos utilizando expresiones regulares. Estas funciones nos permiten localizar patrones específicos y manipular el texto de forma precisa y eficiente.
Principales funciones de búsqueda
El módulo re proporciona varias funciones para buscar patrones en textos, cada una con un propósito específico:
- re.search(): Busca la primera coincidencia del patrón en cualquier parte del texto.
- re.match(): Busca el patrón solo al inicio del texto.
- re.fullmatch(): Verifica si todo el texto coincide exactamente con el patrón.
- re.findall(): Encuentra todas las coincidencias no superpuestas y las devuelve como una lista.
- re.finditer(): Similar a findall(), pero devuelve un iterador de objetos match.
Veamos ejemplos prácticos de cada una:
import re
texto = "Python es un lenguaje versátil. Python es fácil de aprender."
# re.search() - encuentra la primera coincidencia
resultado = re.search(r"Python", texto)
print(f"search: {resultado.group() if resultado else 'No encontrado'}") # Python
# re.match() - busca solo al inicio
resultado = re.match(r"Python", texto)
print(f"match: {resultado.group() if resultado else 'No encontrado'}") # Python
# re.match() en otra posición
resultado = re.match(r"es", texto)
print(f"match 'es': {resultado.group() if resultado else 'No encontrado'}") # No encontrado
# re.fullmatch() - todo el texto debe coincidir
resultado = re.fullmatch(r"Python.*aprender\.", texto)
print(f"fullmatch: {resultado.group() if resultado else 'No encontrado'}") # Coincide con todo el texto
# re.findall() - encuentra todas las coincidencias
coincidencias = re.findall(r"Python", texto)
print(f"findall: {coincidencias}") # ['Python', 'Python']
# re.finditer() - iterador de coincidencias
for match in re.finditer(r"Python", texto):
print(f"finditer: '{match.group()}' en posición {match.start()}-{match.end()}")
Objetos Match y sus métodos
Cuando una búsqueda tiene éxito, las funciones como search()
, match()
y fullmatch()
devuelven un objeto Match que contiene información sobre la coincidencia encontrada:
import re
texto = "Contacto: support@ejemplo.com (Soporte Técnico)"
resultado = re.search(r"(\w+)@(\w+)\.(\w+)", texto)
if resultado:
# Métodos básicos del objeto Match
print(f"Texto completo coincidente: {resultado.group()}") # support@ejemplo.com
print(f"Posición inicial: {resultado.start()}") # 10
print(f"Posición final: {resultado.end()}") # 27
print(f"Tupla (inicio, fin): {resultado.span()}") # (10, 27)
# Acceso a grupos específicos
print(f"Usuario: {resultado.group(1)}") # support
print(f"Dominio: {resultado.group(2)}") # ejemplo
print(f"TLD: {resultado.group(3)}") # com
# Posiciones de grupos específicos
print(f"Posición del usuario: {resultado.start(1)}-{resultado.end(1)}") # 10-17
Funciones de reemplazo
El módulo re ofrece potentes funciones para reemplazar texto basado en patrones:
- re.sub(): Reemplaza todas las coincidencias del patrón.
- re.subn(): Similar a sub(), pero también devuelve el número de sustituciones realizadas.
import re
texto = "El teléfono de Juan es 912345678 y el de Ana es 611234567"
# Reemplazo básico
resultado = re.sub(r"\d{9}", "XXX-XXX-XXX", texto)
print(f"Teléfonos censurados: {resultado}")
# Reemplazo con límite de ocurrencias (count)
resultado = re.sub(r"\d{9}", "XXX-XXX-XXX", texto, count=1)
print(f"Solo primer teléfono censurado: {resultado}")
# re.subn() - devuelve el texto modificado y el número de sustituciones
resultado, num_reemplazos = re.subn(r"\d{9}", "XXX-XXX-XXX", texto)
print(f"Texto modificado: {resultado}")
print(f"Número de reemplazos: {num_reemplazos}") # 2
Reemplazo con funciones
Una característica poderosa de re.sub()
es la capacidad de usar una función para determinar el texto de reemplazo. La función recibe un objeto match y debe devolver la cadena de reemplazo:
import re
# Formatear números de teléfono
def formatear_telefono(match):
numero = match.group(0) # El texto completo que coincidió
return f"{numero[:3]}-{numero[3:6]}-{numero[6:]}"
texto = "Contactos: 912345678, 611234567"
resultado = re.sub(r"\d{9}", formatear_telefono, texto)
print(f"Teléfonos formateados: {resultado}") # 912-345-678, 611-234-567
# Convertir temperaturas de Celsius a Fahrenheit
def celsius_a_fahrenheit(match):
celsius = float(match.group(1))
fahrenheit = celsius * 9/5 + 32
return f"{fahrenheit:.1f}°F"
texto_clima = "Temperaturas: Madrid 25°C, Barcelona 22°C, Sevilla 30°C"
resultado = re.sub(r"(\d+(?:\.\d+)?)°C", celsius_a_fahrenheit, texto_clima)
print(f"Temperaturas convertidas: {resultado}")
Compilación de patrones
Para mejorar el rendimiento cuando usamos el mismo patrón repetidamente, podemos compilarlo previamente con re.compile()
:
import re
import time
# Patrón para validar correos electrónicos
patron_email = re.compile(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")
# Lista de textos para analizar
textos = [
"Contacto: usuario@dominio.com",
"Enviar información a: info@empresa.es",
"Mi dirección es usuario@dominio", # Inválido
"Correo: soporte@servicio.tech"
]
# Usando el patrón compilado
for texto in textos:
match = patron_email.search(texto)
if match:
print(f"Email válido encontrado: {match.group()}")
else:
print(f"No se encontró email válido en: '{texto}'")
# Medición de rendimiento
def test_sin_compilar():
for _ in range(10000):
re.search(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", "usuario@dominio.com")
def test_compilado():
patron = re.compile(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")
for _ in range(10000):
patron.search("usuario@dominio.com")
# Comparación de tiempos
inicio = time.time()
test_sin_compilar()
tiempo_sin_compilar = time.time() - inicio
inicio = time.time()
test_compilado()
tiempo_compilado = time.time() - inicio
print(f"Tiempo sin compilar: {tiempo_sin_compilar:.4f} segundos")
print(f"Tiempo compilado: {tiempo_compilado:.4f} segundos")
print(f"Mejora de rendimiento: {(tiempo_sin_compilar/tiempo_compilado):.2f}x")
Un patrón compilado tiene los mismos métodos que el módulo re (search()
, match()
, sub()
, etc.), pero ya no necesita el patrón como primer argumento.
Flags en búsqueda y reemplazo
Los flags modifican el comportamiento de las operaciones de búsqueda y reemplazo:
import re
texto = """Python es un lenguaje de programación.
python es fácil de aprender.
PYTHON tiene una sintaxis clara."""
# Búsqueda sin flags
resultados = re.findall(r"python", texto)
print(f"Sin flags: {resultados}") # Solo encuentra 'python' en minúsculas
# Búsqueda insensible a mayúsculas/minúsculas
resultados = re.findall(r"python", texto, re.IGNORECASE)
print(f"Con IGNORECASE: {resultados}") # Encuentra todas las variantes
# Múltiples flags combinados con el operador OR (|)
texto_multilinea = """Línea 1: python
Línea 2: PYTHON
Línea 3: Python"""
# re.MULTILINE hace que ^ y $ coincidan con inicio/fin de cada línea
# re.IGNORECASE hace la búsqueda insensible a mayúsculas/minúsculas
resultados = re.findall(r"^línea \d: python$", texto_multilinea,
re.MULTILINE | re.IGNORECASE)
print(f"Con MULTILINE e IGNORECASE: {resultados}")
Los flags también se pueden incluir dentro del patrón usando la sintaxis (?flags)
:
import re
texto = """Python es un lenguaje.
python es fácil."""
# Flags dentro del patrón
resultados = re.findall(r"(?i)python", texto) # Equivalente a re.IGNORECASE
print(f"Flag inline: {resultados}") # ['Python', 'python']
# Flags comunes en forma inline:
# (?i) - IGNORECASE
# (?m) - MULTILINE
# (?s) - DOTALL
# (?x) - VERBOSE
Búsqueda y reemplazo en archivos
Un caso de uso común es procesar archivos de texto línea por línea:
import re
def procesar_archivo(archivo_entrada, archivo_salida, patron, reemplazo):
"""Procesa un archivo línea por línea aplicando un patrón de búsqueda y reemplazo."""
contador = 0
with open(archivo_entrada, 'r', encoding='utf-8') as entrada:
with open(archivo_salida, 'w', encoding='utf-8') as salida:
for linea in entrada:
# Aplicar el reemplazo y contar las sustituciones
nueva_linea, num_reemplazos = re.subn(patron, reemplazo, linea)
contador += num_reemplazos
salida.write(nueva_linea)
return contador
# Ejemplo de uso (comentado para evitar errores si no existen los archivos)
"""
# Normalizar fechas de formato DD/MM/AAAA a AAAA-MM-DD
num_reemplazos = procesar_archivo(
'datos.txt',
'datos_normalizados.txt',
r'(\d{2})/(\d{2})/(\d{4})',
r'\3-\2-\1'
)
print(f"Se normalizaron {num_reemplazos} fechas en el archivo")
"""
Extracción de datos estructurados
Podemos combinar las funciones de búsqueda con estructuras de datos para extraer información estructurada:
import re
# Texto de ejemplo: un log de servidor
log = """
2023-06-15 08:30:45 INFO [Server] Servidor iniciado en puerto 8080
2023-06-15 08:31:23 WARNING [Database] Conexión lenta detectada
2023-06-15 08:32:10 ERROR [Auth] Fallo de autenticación: usuario 'admin'
2023-06-15 08:35:42 INFO [Server] Cliente conectado: 192.168.1.10
"""
# Patrón para extraer componentes del log
patron = r"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) (\w+) \[(\w+)\] (.+)"
# Extraer y estructurar los datos
entradas_log = []
for linea in log.strip().split('\n'):
match = re.search(patron, linea)
if match:
timestamp, nivel, componente, mensaje = match.groups()
entradas_log.append({
'timestamp': timestamp,
'nivel': nivel,
'componente': componente,
'mensaje': mensaje
})
# Filtrar y procesar los datos extraídos
errores = [entrada for entrada in entradas_log if entrada['nivel'] == 'ERROR']
warnings = [entrada for entrada in entradas_log if entrada['nivel'] == 'WARNING']
print(f"Total de entradas: {len(entradas_log)}")
print(f"Errores: {len(errores)}")
print(f"Warnings: {len(warnings)}")
# Mostrar mensajes de error
print("\nMensajes de error:")
for error in errores:
print(f"[{error['timestamp']}] {error['componente']}: {error['mensaje']}")
Validación de entrada con búsqueda y reemplazo
Podemos usar las funciones de búsqueda y reemplazo para validar y limpiar datos de entrada:
import re
def validar_y_formatear_telefono(telefono):
"""Valida y formatea un número de teléfono español."""
# Eliminar todos los caracteres no numéricos
solo_numeros = re.sub(r'\D', '', telefono)
# Validar que sea un número español válido (9 dígitos)
if not re.fullmatch(r'\d{9}', solo_numeros):
return None
# Formatear el número según el tipo (fijo o móvil)
primer_digito = solo_numeros[0]
if primer_digito in '67': # Móvil
return re.sub(r'(\d{3})(\d{3})(\d{3})', r'\1 \2 \3', solo_numeros)
else: # Fijo
return re.sub(r'(\d{3})(\d{2})(\d{2})(\d{2})', r'\1 \2 \3 \4', solo_numeros)
# Probar con diferentes formatos de entrada
telefonos = [
"912345678",
"(91) 234-56-78",
"600 12 34 56",
"6-0-0-1-2-3-4-5-6",
"91.234.56.78",
"1234" # Inválido
]
for telefono in telefonos:
resultado = validar_y_formatear_telefono(telefono)
if resultado:
print(f"'{telefono}' → '{resultado}'")
else:
print(f"'{telefono}' → Formato inválido")
Búsqueda y reemplazo en análisis de texto
Las funciones de búsqueda y reemplazo son útiles para análisis de texto y procesamiento de lenguaje natural básico:
import re
def analizar_texto(texto):
"""Realiza un análisis básico de un texto."""
# Convertir a minúsculas y eliminar puntuación
texto_limpio = re.sub(r'[^\w\s]', '', texto.lower())
# Contar palabras
palabras = re.findall(r'\b\w+\b', texto_limpio)
num_palabras = len(palabras)
# Contar frecuencia de palabras
frecuencia = {}
for palabra in palabras:
if len(palabra) > 3: # Ignorar palabras muy cortas
frecuencia[palabra] = frecuencia.get(palabra, 0) + 1
# Palabras más comunes
palabras_comunes = sorted(frecuencia.items(), key=lambda x: x[1], reverse=True)[:5]
# Contar oraciones
oraciones = re.findall(r'[^.!?]+[.!?]', texto)
num_oraciones = len(oraciones)
return {
'num_palabras': num_palabras,
'num_oraciones': num_oraciones,
'palabras_comunes': palabras_comunes,
'longitud_promedio_oracion': num_palabras / num_oraciones if num_oraciones else 0
}
# Ejemplo
texto_muestra = """
Python es un lenguaje de programación interpretado cuya filosofía hace hincapié en la legibilidad de su código.
Es un lenguaje multiparadigma, ya que soporta orientación a objetos, programación imperativa y programación funcional.
Python es administrado por la Python Software Foundation. Posee una licencia de código abierto.
"""
resultado = analizar_texto(texto_muestra)
print(f"Análisis de texto:")
print(f"- Palabras: {resultado['num_palabras']}")
print(f"- Oraciones: {resultado['num_oraciones']}")
print(f"- Longitud promedio de oración: {resultado['longitud_promedio_oracion']:.1f} palabras")
print(f"- Palabras más comunes:")
for palabra, frecuencia in resultado['palabras_comunes']:
print(f" * '{palabra}': {frecuencia} veces")
Rendimiento y consideraciones prácticas
Al trabajar con expresiones regulares, es importante considerar el rendimiento, especialmente con textos grandes:
import re
import time
# Generar un texto grande para la prueba
texto_grande = "Python es un lenguaje de programación. " * 10000
# Comparar rendimiento de diferentes enfoques
def test_findall():
return re.findall(r"Python", texto_grande)
def test_finditer():
return list(re.finditer(r"Python", texto_grande))
def test_compilado_findall():
patron = re.compile(r"Python")
return patron.findall(texto_grande)
# Medir tiempos
funciones = [test_findall, test_finditer, test_compilado_findall]
for func in funciones:
inicio = time.time()
resultado = func()
tiempo = time.time() - inicio
print(f"{func.__name__}: {len(resultado)} coincidencias en {tiempo:.4f} segundos")
# Consejos prácticos para expresiones regulares eficientes
print("\nConsejos para expresiones regulares eficientes:")
print("1. Compila patrones que uses repetidamente")
print("2. Usa finditer() en lugar de findall() cuando necesites información de posición")
print("3. Evita patrones con cuantificadores voraces (*, +) seguidos de muchas alternativas")
print("4. Usa grupos no capturantes (?:...) cuando no necesites el contenido")
print("5. Ancla tus patrones (^, $, \\b) cuando sea posible para limitar la búsqueda")
Aplicaciones prácticas avanzadas
Las funciones de búsqueda y reemplazo pueden aplicarse a problemas complejos del mundo real:
import re
# Ejemplo: Extraer y analizar datos de un log de servidor web
log_apache = """
192.168.1.10 - - [15/Jun/2023:10:12:01 +0200] "GET /index.html HTTP/1.1" 200 2048
10.0.0.5 - - [15/Jun/2023:10:12:05 +0200] "POST /login HTTP/1.1" 302 0
192.168.1.15 - - [15/Jun/2023:10:12:10 +0200] "GET /images/logo.png HTTP/1.1" 200 4096
10.0.0.8 - - [15/Jun/2023:10:12:15 +0200] "GET /admin HTTP/1.1" 403 1024
192.168.1.20 - - [15/Jun/2023:10:12:20 +0200] "GET /api/data HTTP/1.1" 500 1253
"""
# Patrón para analizar entradas de log de Apache
patron_log = re.compile(r"""
(\d+\.\d+\.\d+\.\d+) # Dirección IP
\s+-\s+-\s+ # Separadores
\[([^\]]+)\] # Fecha y hora entre corchetes
\s+"([A-Z]+)\s+ # Método HTTP
([^\s]+)\s+ # Ruta solicitada
HTTP/[\d.]+"\s+ # Versión HTTP
(\d+)\s+ # Código de estado
(\d+) # Tamaño de respuesta
""", re.VERBOSE)
# Analizar el log
estadisticas = {
'total_solicitudes': 0,
'por_metodo': {},
'por_codigo': {},
'tamaño_total': 0
}
for linea in log_apache.strip().split('\n'):
match = patron_log.search(linea)
if match:
ip, fecha, metodo, ruta, codigo, tamaño = match.groups()
estadisticas['total_solicitudes'] += 1
estadisticas['por_metodo'][metodo] = estadisticas['por_metodo'].get(metodo, 0) + 1
estadisticas['por_codigo'][codigo] = estadisticas['por_codigo'].get(codigo, 0) + 1
estadisticas['tamaño_total'] += int(tamaño)
# Mostrar resultados
print("Análisis de log de servidor web:")
print(f"Total de solicitudes: {estadisticas['total_solicitudes']}")
print("Por método HTTP:")
for metodo, count in estadisticas['por_metodo'].items():
print(f" - {metodo}: {count}")
print("Por código de estado:")
for codigo, count in estadisticas['por_codigo'].items():
print(f" - {codigo}: {count}")
print(f"Tamaño total transferido: {estadisticas['tamaño_total']/1024:.2f} KB")
Las funciones de búsqueda y reemplazo del módulo re son herramientas esenciales para el procesamiento de texto en Python. Dominando estas funciones, puedes realizar desde tareas simples de validación hasta complejos análisis de datos textuales con código conciso y eficiente.
Otras lecciones de Python
Accede a todas las lecciones de Python y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Python
Introducción
Instalación Y Creación De Proyecto
Introducción
Tema 2: Tipos De Datos, Variables Y Operadores
Introducción
Instalación De Python
Introducción
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Estructuras Control Iterativo
Sintaxis
Estructuras Control Condicional
Sintaxis
Testing Con Pytest
Sintaxis
Listas
Estructuras De Datos
Tuplas
Estructuras De Datos
Diccionarios
Estructuras De Datos
Conjuntos
Estructuras De Datos
Comprehensions
Estructuras De Datos
Clases Y Objetos
Programación Orientada A Objetos
Excepciones
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Mixins Y Herencia Múltiple
Programación Orientada A Objetos
Métodos Especiales (Dunder Methods)
Programación Orientada A Objetos
Composición De Clases
Programación Orientada A Objetos
Funciones Lambda
Programación Funcional
Aplicación Parcial
Programación Funcional
Entrada Y Salida, Manejo De Archivos
Programación Funcional
Decoradores
Programación Funcional
Generadores
Programación Funcional
Paradigma Funcional
Programación Funcional
Composición De Funciones
Programación Funcional
Funciones Orden Superior Map Y Filter
Programación Funcional
Funciones Auxiliares
Programación Funcional
Reducción Y Acumulación
Programación Funcional
Archivos Comprimidos
Entrada Y Salida Io
Entrada Y Salida Avanzada
Entrada Y Salida Io
Archivos Temporales
Entrada Y Salida Io
Contexto With
Entrada Y Salida Io
Módulo Csv
Biblioteca Estándar
Módulo Json
Biblioteca Estándar
Módulo Datetime
Biblioteca Estándar
Módulo Math
Biblioteca Estándar
Módulo Os
Biblioteca Estándar
Módulo Re
Biblioteca Estándar
Módulo Random
Biblioteca Estándar
Módulo Time
Biblioteca Estándar
Módulo Collections
Biblioteca Estándar
Módulo Sys
Biblioteca Estándar
Módulo Statistics
Biblioteca Estándar
Módulo Pickle
Biblioteca Estándar
Módulo Pathlib
Biblioteca Estándar
Importar Módulos Y Paquetes
Paquetes Y Módulos
Crear Módulos Y Paquetes
Paquetes Y Módulos
Entornos Virtuales (Virtualenv, Venv)
Entorno Y Dependencias
Gestión De Dependencias (Pip, Requirements.txt)
Entorno Y Dependencias
Python-dotenv Y Variables De Entorno
Entorno Y Dependencias
Acceso A Datos Con Mysql, Pymongo Y Pandas
Acceso A Bases De Datos
Acceso A Mongodb Con Pymongo
Acceso A Bases De Datos
Acceso A Mysql Con Mysql Connector
Acceso A Bases De Datos
Novedades Python 3.13
Características Modernas
Operador Walrus
Características Modernas
Pattern Matching
Características Modernas
Instalación Beautiful Soup
Web Scraping
Sintaxis General De Beautiful Soup
Web Scraping
Tipos De Selectores
Web Scraping
Web Scraping De Html
Web Scraping
Web Scraping Para Ciencia De Datos
Web Scraping
Autenticación Y Acceso A Recursos Protegidos
Web Scraping
Combinación De Selenium Con Beautiful Soup
Web Scraping
Ejercicios de programación de Python
Evalúa tus conocimientos de esta lección Módulo re con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Módulo math
Reto herencia
Excepciones
Introducción a Python
Reto variables
Funciones Python
Reto funciones
Módulo datetime
Reto acumulación
Reto estructuras condicionales
Polimorfismo
Módulo os
Reto métodos dunder
Diccionarios
Reto clases y objetos
Reto operadores
Operadores
Estructuras de control
Funciones lambda
Reto diccionarios
Reto función lambda
Encapsulación
Reto coleciones
Reto funciones auxiliares
Crear módulos y paquetes
Módulo datetime
Excepciones
Operadores
Diccionarios
Reto map, filter
Reto tuplas
Proyecto gestor de tareas CRUD
Tuplas
Variables
Tipos de datos
Conjuntos
Reto mixins
Módulo csv
Módulo json
Herencia
Análisis de datos de ventas con Pandas
Reto fechas y tiempo
Reto estructuras de iteración
Funciones
Reto comprehensions
Variables
Reto serialización
Módulo csv
Reto polimorfismo
Polimorfismo
Clases y objetos
Reto encapsulación
Estructuras de control
Importar módulos y paquetes
Módulo math
Funciones lambda
Reto excepciones
Listas
Reto archivos
Encapsulación
Reto conjuntos
Clases y objetos
Instalación de Python y creación de proyecto
Reto listas
Tipos de datos
Crear módulos y paquetes
Tuplas
Herencia
Reto acceso a sistema
Proyecto sintaxis calculadora
Importar módulos y paquetes
Clases y objetos
Módulo os
Listas
Conjuntos
Reto tipos de datos
Reto matemáticas
Módulo json
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender los conceptos básicos de expresiones regulares y su uso con el módulo re en Python.
- Aprender a construir patrones con caracteres literales, clases predefinidas, anclas y cuantificadores.
- Dominar la creación y uso de grupos de captura, incluyendo grupos nombrados y no capturantes.
- Utilizar las funciones principales de búsqueda y reemplazo del módulo re para manipular texto.
- Aplicar expresiones regulares para validar, extraer y transformar datos en diferentes contextos prácticos.