Los patrones regex son plantillas reutilizables que identifican secuencias específicas de caracteres dentro de un texto - imagínalos como una herramienta de búsqueda con superpoderes que funciona en prácticamente cualquier lenguaje de programación. Ya sea que estés validando un correo electrónico, extrayendo un número de teléfono de un formulario o analizando un archivo de log, un puñado de expresiones regulares bien elegidas cubre el 90% de lo que necesitas. Esta guía reúne los patrones más útiles, explica exactamente qué hace cada uno y te muestra cómo adaptarlos.
Tabla de contenidos
Repaso rápido de sintaxis regex
Antes de entrar en los patrones, aquí tienes una referencia rápida de los bloques fundamentales que verás una y otra vez. Aunque ya hayas trabajado con regex antes, tenerlos todos en un solo lugar siempre viene bien.
| Token | Significado | Ejemplo de coincidencia |
|---|---|---|
.
|
Cualquier carácter excepto salto de línea |
a.c
coincide con
abc
,
a1c
|
\d
|
Cualquier dígito (0-9) |
\d\d
coincide con
42
|
\w
|
Carácter de palabra (letras, dígitos, guion bajo) |
\w+
coincide con
hello_world
|
\s
|
Espacio en blanco (espacio, tabulación, salto de línea) |
\s+
coincide con múltiples espacios
|
^
/
$
|
Inicio / fin de cadena |
^\d+$
coincide únicamente con
123
|
{n,m}
|
Entre n y m repeticiones |
\d{2,4}
coincide de
12
a
1234
|
[abc]
|
Clase de caracteres - cualquiera de a, b, c |
[aeiou]
coincide con cualquier vocal
|
(?:...)
|
Grupo sin captura | Agrupa sin almacenar una referencia inversa |
(?=...)
|
Lookahead positivo | Verifica lo que sigue sin consumirlo |
La guía de expresiones regulares de MDN Web Docs es la mejor referencia para la sintaxis regex en JavaScript, y la mayoría de los patrones que verás a continuación se trasladan directamente a Python, PHP, Java y Ruby con pequeñas diferencias en los flags.
Validación de correo electrónico
El correo electrónico es el caso de uso clásico de regex - y también el que más desarrolladores hacen mal por intentar ser demasiado estrictos. La
especificación RFC 5322
permite técnicamente direcciones como
"very unusual"@example.com
, que casi ningún regex maneja. Para el 99% de la validación de entrada en el mundo real, usa un patrón pragmático:
^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$
Qué hace cada parte:
-
[a-zA-Z0-9._%+\-]+- parte local (antes del @); admite puntos, signos más, guiones y guiones bajos -
@- el símbolo @ literal -
[a-zA-Z0-9.\-]+- nombre de dominio, incluyendo subdominios -
\.[a-zA-Z]{2,}- TLD de al menos 2 caracteres (.io, .com, .museum)
URLs y direcciones web
El reconocimiento de patrones en URLs abarca desde extraer enlaces de texto plano hasta validar el campo de sitio web que introduce un usuario.
https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&\/=]*)
-
https?- coincide tanto conhttpcomo conhttps -
(?:www\.)?- prefijo www opcional -
[-a-zA-Z0-9@:%._+~#=]{1,256}- caracteres del hostname, hasta 256 caracteres -
\.[a-zA-Z0-9()]{1,6}- TLD -
\b(?:[-a-zA-Z0-9()@:%_+.~#?&\/=]*)- ruta, query string y fragmento opcionales
Si solo necesitas validar (no extraer), envuélvelo con los anclajes
^
y
$
.
Números de teléfono
Los números de teléfono son notoriamente complicados porque el formato varía enormemente según el país y los hábitos del usuario. Dos patrones cubren la mayoría de los escenarios:
Formato EE.UU./Canadá (NANP)
^(\+1[-.\s]?)?(\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}$
Coincide con:
555-867-5309
,
(555) 867 5309
,
+1.555.867.5309
,
5558675309
Internacional (formato E.164)
^\+[1-9]\d{6,14}$
E.164 es el formato que utilizan la mayoría de las APIs de telefonía (Twilio, AWS SNS). Comienza con
+
seguido del código de país, sin espacios ni puntuación.
Fechas y horas
El reconocimiento de patrones de fecha es habitual en parsers de logs, validadores de formularios y pipelines de datos. El formato que elijas depende de tu fuente de entrada.
ISO 8601 (YYYY-MM-DD)
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
Formato EE.UU. (MM/DD/YYYY)
^(0[1-9]|1[0-2])\/(0[1-9]|[12]\d|3[01])\/\d{4}$
Hora en formato 24 horas (HH:MM o HH:MM:SS)
^([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?$
Ten en cuenta que estos patrones validan el formato, no la lógica del calendario. Aceptarán
2024-02-31
(el 31 de febrero no existe). Para una validación estricta de fechas, parsea con la librería de fechas de tu lenguaje después de la comprobación con regex.
Validación de fortaleza de contraseñas
Las reglas de contraseñas suelen exigir una combinación de tipos de caracteres y una longitud mínima. Los lookaheads permiten hacer esto de forma limpia sin necesidad de múltiples comprobaciones por separado.
Mínimo 8 caracteres, al menos una mayúscula, una minúscula y un dígito
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$
Fuerte: 8+ caracteres, mayúscula, minúscula, dígito y carácter especial
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]).{8,}$
Cada
(?=.*[...])
es un lookahead que recorre toda la cadena buscando al menos un carácter que coincida. El
.{8,}
final impone la longitud mínima. Puedes sustituir
{8,}
por
{12,}
para exigir un mínimo de 12 caracteres, lo que se alinea con las
directrices NIST SP 800-63B
.
Direcciones IP
IPv4
^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$
Este patrón rechaza correctamente valores como
999.0.0.1
al hacer coincidir cada octeto de forma explícita entre 0 y 255.
IPv6 (simplificado)
^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$
Este patrón maneja el formato completo de 8 grupos. Para la notación comprimida (por ejemplo,
::1
para loopback), el patrón se vuelve considerablemente más complejo - en ese punto, usar una librería de red es más fiable que el regex.
HTML y marcado
Algunos patrones específicos son genuinamente útiles aquí. El consejo general de "no parsees HTML con regex" sigue siendo válido para documentos completos - usa un parser DOM apropiado como BeautifulSoup o DOMParser para eso. Pero para tareas concretas y acotadas, el regex funciona perfectamente.
Eliminar todas las etiquetas HTML
<[^>]*>
Extraer contenido de una etiqueta específica (por ejemplo, <title>)
([^<]*)<\/title>
El grupo de captura 1 contiene el texto del título.
Coincidir con códigos de color hexadecimales HTML
#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})\b
Coincide tanto con la forma abreviada de 3 dígitos (
#fff
) como con la forma completa de 6 dígitos (
#ffffff
).
Patrones de uso cotidiano
Estos aparecen constantemente en todo tipo de proyectos.
Slug (cadena amigable para URLs)
^[a-z0-9]+(?:-[a-z0-9]+)*$
Coincide con cadenas como
my-blog-post-2024
. Sin mayúsculas, sin guiones al inicio o al final, sin guiones dobles.
Número de tarjeta de crédito (formato básico, sin espacios)
^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|6(?:011|5[0-9]{2})[0-9]{12})$
-
Comienza con
4- Visa (13 o 16 dígitos) -
Comienza con
51-55- Mastercard (16 dígitos) -
Comienza con
34o37- Amex (15 dígitos) -
Comienza con
6011o65- Discover (16 dígitos)
Normalización de espacios en blanco (colapsar múltiples espacios)
\s{2,}
Reemplaza las coincidencias con un único espacio para limpiar entradas de usuario desordenadas o texto extraído por scraping.
Solo dígitos
^\d+$
Solo alfanuméricos
^[a-zA-Z0-9]+$
Coincidir con una línea que contenga una palabra (sin distinción de mayúsculas con flag)
^.*\bword\b.*$
El límite de palabra
\b
evita que coincida con
word
dentro de
password
.
Extraer números de versión (semver)
\bv?(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9.]+))?(?:\+([a-zA-Z0-9.]+))?\b
Captura la versión mayor, menor, parche, etiqueta de pre-release y metadatos de compilación de cadenas como
v2.14.0-beta.1+build.42
.
Flags y consejos prácticos
Los patrones regex se comportan de forma diferente según los flags que apliques. Los más habituales son:
| Flag | JS | Python | Efecto |
|---|---|---|---|
| Sin distinción de mayúsculas |
i
|
re.IGNORECASE
|
Trata mayúsculas y minúsculas como iguales |
| Global (buscar todas) |
g
|
re.findall()
|
Devuelve todas las coincidencias, no solo la primera |
| Multilínea |
m
|
re.MULTILINE
|
^
y
$
coinciden con los límites de línea, no con los de la cadena
|
| Dotall |
s
|
re.DOTALL
|
.
también coincide con saltos de línea
|
Algunos hábitos que te ahorrarán tiempo de depuración:
- Prueba siempre con casos límite - cadena vacía, longitud máxima, caracteres Unicode y cadenas que casi pero no del todo son válidas.
-
Usa grupos sin captura
(?:...)cuando no necesites el contenido coincidente - es más rápido y limpio que los grupos de captura. -
Ancla tus patrones de validación
con
^y$para que una subcadena aparentemente válida dentro de una cadena inválida no se cuele. -
Cuidado con el backtracking catastrófico
- los cuantificadores anidados como
(a+)+pueden hacer que el motor de regex se cuelgue con entradas manipuladas. Mantén los cuantificadores simples y específicos. - Usa un tester de regex mientras construyes patrones. regex101.com muestra un desglose de coincidencias en tiempo real, explica cada token y te permite cambiar entre PCRE, JavaScript, Python y otros sabores.
Prueba y valida patrones regex sin adivinar
Crear patrones regex fiables para la validación de entrada es mucho más rápido cuando tienes las herramientas adecuadas a mano. Explora nuestras utilidades gratuitas para desarrolladores para limpiar, comprobar y transformar texto usando patrones regex y más.
Prueba nuestras herramientas gratuitas →
Los cuantificadores greedy (como
.*
) coinciden con todo lo posible y luego hacen backtracking. Los cuantificadores lazy (como
.*?
) coinciden con lo mínimo posible. Por ejemplo, con la cadena
bold
, el patrón
<.*>
coincide con toda la cadena, mientras que
<.*?>
coincide solo con
. Usa cuantificadores lazy cuando extraigas contenido entre delimitadores.
En su mayor parte sí, pero hay diferencias. El módulo
re
de Python usa sintaxis estilo PCRE y admite grupos con nombre mediante
(?P
. JavaScript usa una sintaxis de flags ligeramente distinta y no soporta lookbehinds en motores antiguos (anteriores a ES2018). Para trabajo entre lenguajes, quédate con el subconjunto común: clases de caracteres, cuantificadores, anclajes y grupos básicos.
El regex es perfectamente válido para la validación de formato en producción - se usa en prácticamente todos los frameworks web. Los riesgos vienen de patrones mal escritos que permiten ataques ReDoS (denegación de servicio por regex) mediante backtracking catastrófico. Evita cuantificadores anidados, mantén los patrones específicos y establece siempre un límite razonable de longitud de entrada antes de que el regex se ejecute.
En la mayoría de los motores habituales son equivalentes para entrada ASCII. La diferencia aparece con Unicode:
\d
en algunos motores (como Python 3 con modo Unicode) coincide con dígitos de otros sistemas de escritura, como los numerales árabe-índicos. Si quieres estrictamente los dígitos ASCII del 0 al 9, usa
[0-9]
para ser explícito. Para la mayoría de la validación de formularios web, la distinción no importa.
Necesitas dos cosas: el
flag dotall
(para que
.
coincida con saltos de línea) y posiblemente el
flag multilínea
(para que
^
y
$
anclen a cada línea en lugar de a toda la cadena). En JavaScript usa
/pattern/ms
. En Python, combina
re.DOTALL | re.MULTILINE
. Sin dotall,
.
se detiene en los saltos de línea y tu patrón no abarcará varias líneas.