Expresiones regulares a la vista
·
Resumen del curso
1
El pago desaparecido: buscar el texto tal cual
2
El coche que se dio a la fuga: clases de caracteres
3
La guía telefónica rota: cuantificadores
4
Los registros falsos: anclas y validación
5
Fechas por todas partes: grupos y alternativas
6
El acceso de las 3 de la madrugada: grupos con nombre y objetos Match
7
La víspera de la noticia: sustitución y división
8
El desafío del Backtracker: codicioso, perezoso y posesivo
9
Las reglas de la caja fuerte: lookaround
10
El mismo modus operandi: retrorreferencias y condicionales
11
La regex ilegible: flags y compilación
12
El Backtracker, desenmascarado: repaso y un tokenizador
Tiempo 0:00–0:50
CASE-001
Grep & Co. Agencia de Detectives de Datos
Expediente
Cliente
El dueño del cibercafé «Level Up»
Pruebas
El log del servidor de pagos. Un cliente asegura que pagó 4,99 dólares, pero no hay ningún registro, y está protestando.
Para cerrar el caso
Encontrar en el log las líneas con error y quedarse solo con los pagos de exactamente $4.99.
Primera mañana de trabajo. La directora deja la taza de café sobre la mesa y te acerca una hoja. «Ayer vino el dueño del cibercafé. Un cliente dice que pagó 4,99 dólares y no aparece en ningún sitio. Los logs no mienten. Búscalo».
El log es este. Hoy vas a buscar pruebas en estas cinco líneas.
2026-10-20 09:12:01 INFO PAY user=kim amount=$4.99 status=OK
2026-10-20 09:12:07 INFO PAY user=lee amount=$14.99 status=OK
2026-10-20 09:13:44 ERROR PAY user=park amount=$4.99 status=TIMEOUT
2026-10-20 09:15:02 INFO PAY user=choi amount=$4999 status=OK
2026-10-20 09:16:30 ERROR DB connection lostUna expresión regular (regular expression, o regex) es un pequeño lenguaje para describir la forma del texto que quieres encontrar. En Python se usa con el módulo re. La regex más sencilla es texto sin más: el patrón ERROR encuentra el texto ERROR.
import re
log = "2026-10-20 09:13:44 ERROR PAY user=park"
m = re.search("ERROR", log)
print(m) # <re.Match object; span=(20, 25), match='ERROR'>re.search(patrón, cadena) recorre la cadena desde el principio y busca el primer sitio donde aparece el patrón.None.Laboratorio de pruebas
re.search(r"", text)
Valor devuelto
El objeto Match es la prueba de que «se encontró algo» y, a la vez, un informe que dice qué se encontró y dónde.
m = re.search("ERROR", log)
if m: # verdadero si encontró algo; None es falso
print(m.group()) # ERROR (el texto encontrado)
print(m.span()) # (20, 25) (posición inicial, posición final)if m:. Si no encontró nada, m es None, y llamar a m.group() lanza un AttributeError.span() no se incluye. Es la misma regla por la que log[20:25] es "ERROR".Casi todos los caracteres se encuentran a sí mismos. Pero estos 14 son metacaracteres: en una regex tienen un significado especial.
. ^ $ * + ? { } [ ] \ | ( )Hoy solo veremos el primero, ., que significa un carácter cualquiera, menos el salto de línea. Los demás irán saliendo, uno por lección.
re.search("a.c", "abc") # coincide: la b ocupa el lugar del .
re.search("a.c", "a-c") # coincide: el - también es un carácter cualquiera
re.search("a.c", "ac") # None: el . siempre ocupa exactamente un carácter
re.search("a.c", "a\nc") # None: el salto de línea no cuenta para el .El consejo de Dot
Yo me subo a cualquier sitio de la agencia: mesas, sillas, hasta el teclado de la directora. Solo hay una cosa que no puedo cruzar: la ventana (el salto de línea). Por eso me llamo Dot (.). Dicen que, si algún día alguien me abre la ventana, podré pasar al otro lado.
Laboratorio de pruebas
re.search(r"", text)
Valor devuelto
Volvamos al caso. Supongamos que las cinco líneas del log de arriba están en una cadena llamada pay_log. Si escribes 4.99 para buscar los pagos de 4,99 dólares, ¿qué pasa?
re.findall("4.99", pay_log) # ['4.99', '4.99', '4.99', '4999'] ← ¿cuatro?Deberían salir dos resultados y salen cuatro. Se ha colado el final de $14.99, que también es 4.99, y como . significa «un carácter cualquiera», ha entrado incluso el 4999 de $4999. Para buscar un metacarácter tal cual, se le pone delante una barra invertida \. \. es un punto de verdad.
$ también es un metacarácter. Su significado lo veremos en la lección 4; por ahora, recuerda solo que «escrito tal cual, no busca el signo del dólar». Así que la respuesta correcta es \$4\.99.
re.findall(r"\$4\.99", pay_log) # ['$4.99', '$4.99']Laboratorio de pruebas
re.search(r"", text)
Valor devuelto
Arriba escribimos r"\$4\.99", con una r delante de las comillas. Esto se llama cadena raw (cadena «en bruto»).
La barra invertida también es especial en las cadenas de Python: "\n" es un salto de línea y "\t", un tabulador. Por eso, si escribes una regex en una cadena normal, Python interpreta primero las barras invertidas y re recibe un patrón que no es el que querías.
print(len("\b")) # 1 ← Python ha convertido \b en un solo carácter, el «retroceso»
print(len(r"\b")) # 2 ← la barra invertida y la b, dos caracteres tal cualr"..." le pasa las barras invertidas a re sin tocarlas. Las regex se escriben siempre como cadenas raw."\d", salta un SyntaxWarning. Con una cadena raw no hay aviso.El dueño del cibercafé te pide: «El usuario del cliente es kim.99+, búscame eso también». Si escribes ese texto directamente como patrón, . y + se interpretan como metacaracteres. Cuando quieras buscar tal cual algo que ha escrito una persona, re.escape pone la barra invertida delante de cada metacarácter por ti.
print(re.escape("kim.99+")) # kim\.99\+
re.search(re.escape("kim.99+"), "user=kim.99+") # coincideEn resumen: las líneas con error se encuentran con ERROR, y los pagos de exactamente 4,99 dólares, con \$4\.99. Si juntas las dos condiciones, queda al descubierto que el pago del cliente park falló con un error TIMEOUT y nunca quedó registrado.
for line in pay_log.splitlines():
if re.search("ERROR", line) and re.search(r"\$4\.99", line):
print(line)
# 2026-10-20 09:13:44 ERROR PAY user=park amount=$4.99 status=TIMEOUTInforme de caso cerrado — A las 09:13:44 el servidor de pagos dio el pago por fallido por tiempo de espera agotado, pero en la pantalla del cliente aparecía como completado. Se recomienda al dueño del cibercafé que haga el reembolso.
INFO. ¿Cuántas hay?\$1.\.99? Intenta adivinarlo antes de comprobarlo en el laboratorio.re.escape("1+1=2? [yes]") y luego ejecútalo.La libreta de la directora
Casi todos los caracteres se encuentran a sí mismos. Solo son especiales los 14 metacaracteres . ^ $ * + ? { } [ ] \ | ( )
. es un carácter cualquiera menos el salto de línea. Un punto de verdad es \.
re.search devuelve un Match o None. Se comprueba con if m: y se mira con m.group() y m.span().
Las regex, siempre como cadenas raw r"...".
Para buscar tal cual lo que escribe una persona, re.escape.
← Anterior
Resumen del curso
Siguiente →
Lección 2 · El coche que se dio a la fuga: clases de caracteres
Recibe avisos de nuevas lecciones
Te avisaremos por correo cuando este curso tenga lecciones nuevas o se abra un curso de continuación.
R
ReflexKR
Aprende Python y Reflex haciendo. Todos los ejemplos se ejecutaron y verificaron en Reflex 0.10.0.
ReflexKR es gratis y sin banners publicitarios. Si te ayudó, puedes apoyarlo con un café. ☕ Invítanos un café
Aviso de afiliados© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
Preguntas y respuestas
Pregunta lo que quieras sobre esta lección. Aquí se reúnen las preguntas de todas las versiones de idioma de esta página.