# regex-con-python-desde-cero
Regex con Python desde Cero
Volver a la portada del cursoSintaxis de Regex
Sección 1 · Introducción a Regex
Sintaxis de Regex
La bandeja de soporte de PyShop tiene 600 tickets y 97,737 caracteres. El patrón PS-\d{5} encuentra el pedido en 469 de ellos; los otros 131 lo escriben como ps-20458 o PS 12345. Para llegar a 600 no hace falta más código, sino más vocabulario: clases, atajos, anclas y banderas. Esta lectura es la tabla de referencia de ese vocabulario, con un ejemplo real de la bandeja para cada pieza.
1. Literales y metacaracteres
En una expresión regular casi todos los caracteres son literales: P busca una P y - busca un guion. Solo 14 caracteres tienen un significado especial:
| Metacarácter | Significado | Ejemplo |
|---|---|---|
. | cualquier carácter salvo el salto de línea | P. en «PS» → «PS» |
^ y $ | inicio y fin de la cadena (o de cada línea con re.MULTILINE) | ^Ticket |
* + ? | cero o más, una o más, cero o una repeticiones | \d+ |
{ } | repetición exacta o en rango | \d{5} |
[ ] | clase de caracteres: uno de los listados | [Pp] |
\ | escape o atajo | \., \d |
| | alternancia: una opción u otra | PS|ps |
( ) | grupo | (\d{5}) |
Las repeticiones y los grupos tienen sus propias lecciones; aquí interesa reconocerlos para saber cuándo escaparlos.
2. Escapes, raw strings y re.escape
Para buscar un metacarácter como literal se antepone una barra invertida. El caso típico es el punto decimal: en «Total 1249.50 o 1249x50», el patrón \d+.\d+ devuelve ['1249.50', '1249x50'], porque el punto acepta cualquier carácter; \d+\.\d+ devuelve solo ['1249.50'].
Las barras invertidas chocan con las de Python: en una cadena normal "\n" es un salto de línea (longitud 1), mientras que r"\n" son dos caracteres, la barra y la n (longitud 2). Por eso los patrones se escriben siempre como raw strings r"…": el texto llega intacto al módulo re. Si el patrón sale de un texto fijo, como un monto, re.escape escapa todo lo necesario:
import re
print(len("\n"), len(r"\n")) # 1 2
print(re.escape("$1,249.50")) # \$1,249\.50
texto = "Total 1249.50 o 1249x50"
print(re.findall(r"\d+.\d+", texto)) # ['1249.50', '1249x50']
print(re.findall(r"\d+\.\d+", texto)) # ['1249.50']
3. Clases, rangos y negación
Una clase […] coincide con un carácter de los listados. [Pp][Ss][- ]\d{5} acepta mayúscula o minúscula y guion o espacio: encuentra el pedido en los 600 tickets. Dentro de la clase se pueden usar rangos ([0-9], [a-z]) y, si el primer carácter es ^, la clase se niega: [^\d\s] significa «ni dígito ni espacio», y en «PS-4821 3» devuelve ['P', 'S', '-']. Dentro de una clase casi todos los metacaracteres pierden su significado: [.] es un punto literal.
4. Atajos y Unicode
| Atajo | Equivale a | Negado |
|---|---|---|
\d | dígito | \D |
\w | carácter de palabra: letra, dígito o guion bajo | \W |
\s | espacio, tabulador, salto de línea | \S |
Con patrones de tipo str, Python usa Unicode por defecto: \w+ en «Sofía pagó 899» devuelve ['Sofía', 'pagó', '899']. Con la bandera re.ASCII, \w se reduce a [a-zA-Z0-9_] y el mismo texto se rompe en ['Sof', 'a', 'pag', '899']. En texto en español conviene dejar Unicode.
5. Anclas y re.MULTILINE
Las anclas no consumen caracteres: marcan posiciones. ^ y $ son el inicio y el fin; \A y \Z son el inicio y el fin de la cadena completa, sin importar banderas; \b es un borde de palabra y \B su negación. En «favorito favor», favor coincide 2 veces y \bfavor\b solo 1, porque «favorito» sigue con letras.
La bandeja unida en una sola cadena tiene 600 líneas que dicen Ticket T-0001, Ticket T-0002… El patrón ^Ticket T-\d{4}$ encuentra 0, porque sin banderas ^ solo es el inicio del texto y $ el final. Con re.MULTILINE ambos se aplican a cada línea y encuentra 600:
bandeja = "\n\n".join(generar_tickets())
patron = r"^Ticket T-\d{4}$"
print(len(re.findall(patron, bandeja))) # 0
print(len(re.findall(patron, bandeja, re.MULTILINE))) # 600
6. El punto y re.DOTALL
El punto no cruza saltos de línea. En el primer ticket, Ticket.+De no encuentra nada, porque «Ticket» y «De» están en líneas distintas. Con re.DOTALL (alias re.S) el punto acepta también \n y Ticket.+?De coincide una vez. Las banderas se combinan con |: re.IGNORECASE | re.MULTILINE.
Trampas comunes
- Olvidar la
r."\b"sin raw string es un retroceso (backspace), no un borde de palabra, y el patrón deja de coincidir sin dar error. - Punto sin escapar.
\d+.\d+acepta «1249x50». Para el separador decimal usa\.. - Confundir
^dentro y fuera de la clase. En^PSes ancla; en[^PS]es negación. - Esperar que
^funcione por línea. Sinre.MULTILINE, solo marca el inicio del texto completo. - Usar
re.ASCIIcon texto en español. Parte las palabras con acentos.
Cierre
En el notebook fundamentos-y-sintaxis se recorre esta tabla sobre la bandeja completa: del 469 inicial al 600 con una clase y luego con re.IGNORECASE. Antes de escribir un patrón nuevo, pruébalo en un texto con un caso que debe coincidir y otro que no; el segundo es el que detecta los errores.