re - Expresiones Regulares
El módulo re busca, encuentra y sustituye texto mediante expresiones regulares. Compila patrones para su reutilización; usa cadenas crudas r"..." para escapes legibles; prefiere los métodos de str cuando las expresiones regulares son excesivas.
Receta
import re
EMAIL = re.compile(r"^[\w.+-]+@[\w-]+\.[\w.-]+$")
def valid_email(value: str) -> bool:
return bool(EMAIL.match(value))Cuándo usar esto:
- Análisis y extracción de logs
- Tokenización de texto estructurado pero irregular
- Validación con límites de patrones conocidos
- Sustituciones tipo sed
- División por espacios en blanco variables
Ejemplo de Trabajo
import re
LOG_LINE = re.compile(
r"^(?P<level>INFO|ERROR)\s+(?P<msg>.+)$"
)
def parse_log_lines(text: str) -> list[dict[str, str]]:
rows = []
for line in text.strip().splitlines():
m = LOG_LINE.match(line)
if m:
rows.append(m.groupdict())
return rows
sample = "INFO started\nERROR disk full\n"
print(parse_log_lines(sample))
redacted = re.sub(r"\b\d{4}-\d{4}-\d{4}-\d{4}\b", "[CARD]", "4111-1111-1111-1111")
print(redacted)Lo que esto demuestra:
- Grupos nombrados mediante
(?P<nombre>...) matchancla el inicio;searchescanea en cualquier lugarsubreemplaza patrones de datos sensibles- Compila una vez a nivel de módulo para rutas críticas
Inmersión Profunda
Métodos Comunes
| Método | Propósito |
|---|---|
re.search | Primera coincidencia en cualquier lugar |
re.match | Inicio de la cadena |
re.findall | Todas las no superpuestas |
re.sub | Reemplazar |
Flags
re.IGNORECASE,re.MULTILINE,re.DOTALLre.compile(..., flags)combina
Errores Comunes
- Backtracking catastrófico - cuantificadores anidados maliciosos. Solución: límites posesivos, grupos atómicos o tiempo de espera del motor de expresiones regulares.
- Exceso de expresiones regulares - validación de correo electrónico/URL incompleta frente al RFC real. Solución: patrón pragmático + verificación secundaria.
- Recompilación en bucle - lento. Solución: patrones compilados a nivel de módulo.
- Confusión entre
matchysearch-matchomite el medio de la cadena. Solución: elegir el método correcto. \wdependiente de la configuración regional - sorpresas de Unicode. Solución: clases de caracteres explícitas[A-Za-z0-9_].
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| str.split/partition | Delimitador fijo | Patrón variable |
| parsimonious/lark | Lenguajes de gramática | Extracción simple |
| pandas str.extract | Datos tabulares | Cadena única |
Preguntas Frecuentes
¿Cadena cruda requerida?
No es requerida pero la claridad r"\n" vs "\\n" es muy recomendada.
¿Grupos en findall?
Devuelve tuplas si hay múltiples grupos de captura; usa finditer para objetos.
¿Codicioso vs. perezoso?
Cuantificadores perezosos *?, +? - coinciden con el tramo mínimo.
¿Expresión regular verbosa?
re.compile(r"...", re.VERBOSE) permite comentarios y espacios en blanco en el patrón.
¿Unicode?
Patrones de cadena unicode por defecto en Python 3; usa (?a) para solo ASCII cuando sea necesario.
¿Conteo de reemplazo?
sub(pattern, repl, s, count=1) limita los reemplazos.
¿Lookahead?
(?=...) lookahead positivo - afirma sin consumir.
¿Probar expresiones regulares?
Casos de prueba en tabla en pytest; documenta el patrón en el docstring.
¿JSON en expresiones regulares?
No analices JSON con expresiones regulares - usa el módulo json.
¿re vs regex PyPI?
El módulo regex añade características; la biblioteca estándar es suficiente para la mayoría de los servicios.
Relacionados
- json y Serialización - analizar estructurado en su lugar
- subprocess - analizar la salida de comandos
- Descripción General de la Biblioteca Estándar - mapa
- Cadenas y f-strings - conceptos básicos de texto
Versiones de la pila: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.