Regex de validación de email que realmente funciona (2026)
La validación de email parece sencilla hasta que te sientas a escribirla. Lo que parece una simple verificación de formato resulta involucrar una especificación RFC de 6,000 caracteres, nombres de dominio internacionales, cadenas entre comillas y casos extremos que rompen casi todos los regex que encuentras en Stack Overflow. Esta guía cubre los patrones prácticos que funcionan, las compensaciones entre ellos y cuándo dejar de intentar ser ingenioso con regex.
Por qué la validación de email es más difícil de lo que crees
El formato de dirección de email está definido por RFC 5322 y sus predecesores. La especificación completa permite algunas direcciones de aspecto sorprendentemente extraño que son técnicamente válidas:
"spaces in quotes"@example.com— cadenas entre comillas en la parte localuser+tag@example.com— direccionamiento plus (ampliamente usado para filtros en Gmail)user@subdomain.example.co.uk— múltiples subdominios y ccTLDsuser@[192.168.1.1]— literales de dirección IP como dominiovery.unusual."@".unusual.com@example.com— técnicamente válido pero casi nunca vistouser@xn--nxasmq6b.com— nombres de dominio internacionalizados (Punycode)
Un regex completamente compatible con RFC 5322 necesitaría manejar todos estos, mientras también rechaza direcciones que no cumplen las reglas básicas de formato. El resultado es un patrón de 1000 caracteres que es esencialmente imposible de mantener. En la práctica, el objetivo no es la compatibilidad total con el RFC — es detectar errores tipográficos sin bloquear direcciones reales.
El regex simple (suficiente para el 99% de los casos)
Para la mayoría de las aplicaciones, este patrón mínimo es la elección correcta. Valida la estructura esencial — algo antes de un @, un dominio y un TLD — sin falsos negativos en direcciones legítimas:
/^[^\s@]+@[^\s@]+\.[^\s@]+$/
Desglose:
^— inicio de la cadena[^\s@]+— uno o más caracteres que no son espacio en blanco ni@(la parte local)@— arroba literal[^\s@]+— uno o más caracteres que no son espacio en blanco ni@(el dominio)\.— un punto literal[^\s@]+— uno o más caracteres (el TLD)$— fin de la cadena
Lo que acepta y rechaza correctamente:
Válidos (aceptados):
Inválidos (rechazados):
La principal debilidad es que acepta user@@example.com y a@b.c (técnicamente válido pero sospechoso). Para la mayoría de formularios de registro e inputs de API, esta es una compensación aceptable.
El regex completo (compatible con RFC 5322)
Cuando necesitas una validación más estricta — por ejemplo, en un sistema de envío de emails donde las direcciones inválidas causan rebotes y dañan la reputación del remitente — un patrón más riguroso está justificado. Este es un patrón derivado de RFC 5322 ampliamente citado:
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
Este patrón es más largo pero maneja significativamente más casos. Desglose de las partes clave:
- Parte local (antes de @): Ya sea una secuencia de caracteres permitidos con segmentos opcionales separados por puntos
[^<>()...]+(\.[^<>()...]+)*, o una cadena entre comillas".+"para direcciones como"john doe"@example.com. - Dominio (después de @): Ya sea un literal de dirección IP entre corchetes
\[[0-9]{1,3}...\], o un nombre de host estándar con un TLD de al menos 2 caracteres([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}. - TLD mínimo de 2 caracteres: Rechaza TLDs de un solo carácter mientras acepta los largos como
.museumo.technology.
Casos adicionales que este patrón maneja correctamente:
Aún rechazados correctamente:
Validación de email en JavaScript
Aquí hay implementaciones prácticas en JavaScript listas para copiar y pegar usando ambos patrones:
Función de validación simple
/** * Valida formato de email para la mayoría de casos de uso. * Rápido, legible, muy pocos falsos negativos. */ function isValidEmail(email) { const pattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return pattern.test(email.trim()); } // Uso isValidEmail("user@example.com"); // true isValidEmail("not-an-email"); // false isValidEmail("user+tag@gmail.com"); // true
Validación más estricta con retroalimentación detallada
function validateEmail(email) { const trimmed = email.trim(); if (!trimmed) { return { valid: false, error: "El email es requerido" }; } if (trimmed.length > 254) { return { valid: false, error: "Dirección de email muy larga (máximo 254 caracteres)" }; } if (!trimmed.includes("@")) { return { valid: false, error: "Falta el símbolo @" }; } const [local, ...domainParts] = trimmed.split("@"); const domain = domainParts.join("@"); if (!local || local.length > 64) { return { valid: false, error: "Parte local inválida (antes de @)" }; } if (!domain || !domain.includes(".")) { return { valid: false, error: "Dominio inválido (falta TLD)" }; } const rfcPattern = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; if (!rfcPattern.test(trimmed)) { return { valid: false, error: "Formato de email inválido" }; } return { valid: true, email: trimmed.toLowerCase() }; } // Uso const result = validateEmail(" User@Example.COM "); // { valid: true, email: "user@example.com" }
Validación de email con HTML5
Antes de recurrir a JavaScript, considera lo que el navegador te da gratis. El elemento input type="email" tiene validación incorporada que se ejecuta al enviar el formulario:
<!-- Validación incorporada básica --> <input type="email" name="email" required> <!-- Con patrón personalizado para validación más estricta --> <input type="email" name="email" required pattern="[^\s@]+@[^\s@]+\.[^\s@]+" title="Por favor ingresa una dirección de email válida" >
El algoritmo incorporado del navegador para type="email" sigue la especificación HTML5 (un subconjunto simplificado de RFC 5322). Rechaza no-emails obvios, muestra un tooltip de validación nativo y funciona sin JavaScript. El atributo pattern permite agregar restricciones adicionales.
Limitaciones a tener en cuenta: la validación incorporada solo se activa al enviar el formulario, no mientras el usuario escribe. Para retroalimentación en tiempo real, necesitas JavaScript. Además, la pseudo-clase CSS :invalid permite estilizar inputs inválidos, pero se activa incluso en campos vacíos no tocados a menos que también uses :not(:placeholder-shown):
/* Solo mostrar borde rojo después de que el usuario haya interactuado */ input[type="email"]:not(:placeholder-shown):invalid { border-color: #ef4444; outline-color: #ef4444; } input[type="email"]:not(:placeholder-shown):valid { border-color: #34d399; }
Casos extremos comunes
Estos son los casos que hacen fallar a la mayoría de implementaciones de validación de email:
Direccionamiento plus (subaddressing)
user+tag@gmail.com es válido y ampliamente usado. Gmail, Outlook y la mayoría de proveedores de email modernos lo soportan para filtrado. Tu regex no debe rechazar el carácter + en la parte local. Muchos patrones excesivamente restrictivos fallan en esto.
Subdominios
first.last@mail.company.co.uk es un email válido con puntos tanto en la parte local como en el dominio. El dominio tiene tres niveles. Un buen patrón debe manejar múltiples etiquetas separadas por puntos en el dominio.
TLDs largos
Los TLDs ya no están restringidos a dos o tres caracteres. .museum, .photography, .technology y cientos de otros gTLDs son válidos. Cualquier regex que imponga una longitud máxima de TLD de 4 o 6 caracteres producirá falsos negativos. Impón solo un mínimo (2 caracteres) y ningún máximo.
Dominios internacionales (IDN)
Los nombres de dominio pueden contener caracteres no ASCII codificados como Punycode. user@münchen.de es válido — el dominio real es xn--mnchen-3ya.de en forma ASCII. La mayoría de los patrones regex no pueden validar Punycode directamente; confía en una librería dedicada de validación de email si se requiere soporte IDN.
Literales de dirección IP
user@[192.168.1.1] es técnicamente válido según RFC 5321 pero casi nunca se usa en la práctica. A menos que estés construyendo una implementación SMTP, puedes ignorar este caso de forma segura.
No sobre-valides
Este es el consejo práctico más importante de este artículo: el propósito de la validación de email del lado del cliente es detectar errores tipográficos, no verificar la capacidad de entrega.
Ningún regex puede decirte si una dirección de email realmente existe o si su bandeja de entrada está aceptando correo. Solo enviar al buzón puede confirmar eso. Sobre-validar (rechazar direcciones que tu regex marca incorrectamente como inválidas) pierde usuarios reales. Sub-validar (aceptar direcciones mal formadas) te cuesta un rebote.
El enfoque correcto es una estrategia de dos capas:
- Usa un regex simple para detectar errores obvios de formato (falta el
@, falta el TLD, espacios). - Envía un email de confirmación o verificación para confirmar que la dirección es real y el usuario la controla.
Un email de confirmación es la única puerta confiable. Todo lo demás es una heurística. Si te encuentras debatiendo si rechazar user@localhost o a@b.io, da un paso atrás — envía el email y deja que la capa SMTP lo maneje.
Comparación de patrones regex populares para email
Aquí hay una comparación práctica de los patrones más comúnmente usados, incluyendo sus compensaciones:
| Patrón | Tipo | Ventajas | Desventajas | Cobertura |
|---|---|---|---|---|
| /^[^\s@]+@[^\s@]+\.[^\s@]+$/ | Simple | Legible, mínimos falsos negativos, rápido | Acepta a@@b.c, muy permisivo |
~95% |
| /^[\w.+-]+@[\w-]+\.[\w.]{2,}$/ | Común | Corto, maneja la mayoría de emails del mundo real | Rechaza caracteres especiales válidos en la parte local | ~92% |
| /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ | Equilibrado | Ampliamente usado, buen equilibrio de rigurosidad y cobertura | Rechaza algunos locales válidos con cadenas entrecomilladas | ~97% |
| /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}...)/ | RFC 5322 | Maneja cadenas entrecomilladas, literales IP, TLDs largos | Largo, difícil de leer, aún no 100% compatible con RFC | ~99% |
El patrón "equilibrado" completo
El tercer patrón en la tabla anterior es la elección más práctica para uso en producción cuando quieres más que el patrón simple pero no la complejidad completa de RFC 5322:
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
Desglose:
[a-zA-Z0-9._%+-]+— parte local: alfanuméricos más.,_,%,+,-@— arroba requerida[a-zA-Z0-9.-]+— dominio: alfanuméricos, guiones, puntos (maneja subdominios)\.— punto separador antes del TLD[a-zA-Z]{2,}— TLD: al menos 2 letras, sin máximo (maneja TLDs largos)
Usar una librería en lugar de crear la tuya propia
Para aplicaciones donde la validez del email es crítica (sistemas de email transaccional, flujos de registro B2B SaaS), considera una librería de validación dedicada en lugar de escribir regex tú mismo:
// Node.js — validator.js (la más popular) import validator from 'validator'; validator.isEmail('user@example.com'); // true // Node.js — email-validator (ligera) import { validate } from 'email-validator'; validate('user@example.com'); // true // Python — email-validator (compatible con RFC) # pip install email-validator from email_validator import validate_email, EmailNotValidError try: info = validate_email("user@example.com") except EmailNotValidError as e: print(str(e))
Prueba tu regex de email
La mejor forma de entender cualquier regex es ejecutarlo contra un conjunto completo de entradas de prueba — tanto direcciones válidas que esperas aceptar como inválidas que necesitas rechazar. Nuestro Regex Tester te permite pegar cualquiera de los patrones anteriores, construir un conjunto de pruebas y ver resultados de coincidencia resaltados en tiempo real.
Prueba tu regex de email en vivo
Pega cualquier patrón regex de email y pruébalo contra tus propias entradas. Soporta flags, grupos de captura y matching multilínea. Se ejecuta completamente en tu navegador.
Abrir Regex Tester →Herramientas de desarrollo relacionadas
- Regex Tester — prueba y depura expresiones regulares con resaltado en vivo
- Inspector ENV — valida archivos
.envy detecta secretos expuestos - Codificador / Decodificador URL — codifica y decodifica componentes de URL y query strings
- Ver todas las herramientas gratuitas para desarrolladores