Saltar al contenido

¿Cómo validar una dirección de correo electrónico usando una expresión regular?

Ya no tienes que buscar más por todo internet porque estás al lugar necesario, tenemos la solución que necesitas y sin complicaciones.

Solución:

La expresión regular totalmente compatible con RFC 822 es ineficiente y oscura debido a su longitud. Afortunadamente, RFC 822 fue reemplazado dos veces y la especificación actual para direcciones de correo electrónico es RFC 5322. RFC 5322 conduce a una expresión regular que se puede entender si se estudia durante unos minutos y es lo suficientemente eficiente para su uso real.

Se puede encontrar una expresión regular compatible con RFC 5322 en la parte superior de la página en http://emailregex.com/, pero utiliza el patrón de dirección IP que flota en Internet con un error que permite 00 para cualquiera de los valores decimales de bytes sin signo en una dirección delimitada por puntos, lo cual es ilegal. El resto parece ser consistente con la gramática RFC 5322 y pasa varias pruebas usando grep -Po, incluidos los casos de nombres de dominio, direcciones IP, malas y nombres de cuentas con y sin comillas.

Corrigiendo el 00 error en el patrón de IP, obtenemos una expresión regular que funciona y bastante rápida. (Raspe la versión renderizada, no la rebaja, para el código real).

(?:[a-z0-9!#$%&’*+/=?^_`~-]+ (?: .[a-z0-9!#$%&’*+/=?^_`~-]+) * | “(?:[x01-x08x0bx0cx0e-x1fx21x23-x5bx5d-x7f]| \[x01-x09x0bx0cx0e-x7f]) * “) @ (? 🙁 ?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])? .) +[a-z0-9](?:[a-z0-9-]*[a-z0-9])? | [(?:(?:(2(5[0-5]|[0-4][0-9]) | 1[0-9][0-9]|[1-9]?[0-9])) .) 3 (? 🙁 2 (5[0-5]|[0-4][0-9]) | 1[0-9][0-9]|[1-9]?[0-9]) |[a-z0-9-]*[a-z0-9]:( ?:[x01-x08x0bx0cx0e-x1fx21-x5ax53-x7f]| \[x01-x09x0bx0cx0e-x7f]) +) ])

o:

(?:[a-z0-9!#$%&'*+/=?^_`~-]+(?:.[a-z0-9!#$%&'*+/=?^_`~-]+)*|"(?:[x01-x08x0bx0cx0e-x1fx21x23-x5bx5d-x7f]|\[x01-x09x0bx0cx0e-x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])).)3(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[x01-x08x0bx0cx0e-x1fx21-x5ax53-x7f]|\[x01-x09x0bx0cx0e-x7f])+)])

Aquí hay un diagrama de la máquina de estados finitos para la expresión regular anterior que es más clara que la expresión regular en sí
ingrese la descripción de la imagen aquí

Los patrones más sofisticados en Perl y PCRE (biblioteca de expresiones regulares utilizada, por ejemplo, en PHP) pueden analizar correctamente RFC 5322 sin problemas. Python y C # también pueden hacer eso, pero usan una sintaxis diferente a la de los dos primeros. Sin embargo, si se ve obligado a utilizar uno de los muchos lenguajes de coincidencia de patrones menos potentes, es mejor utilizar un analizador sintáctico real.

También es importante comprender que validarlo según el RFC no le dice absolutamente nada sobre si esa dirección realmente existe en el dominio proporcionado, o si la persona que ingresa la dirección es su true dueño. Las personas inscriben a otros en listas de correo de esta manera todo el tiempo. Arreglar eso requiere un tipo de validación más elegante que implica enviar a esa dirección un mensaje que incluye un token de confirmación que debe ingresarse en la misma página web que la dirección.

Los tokens de confirmación son la única forma de saber que obtuvo la dirección de la persona que la ingresó. Es por eso que la mayoría de las listas de correo ahora usan ese mecanismo para confirmar suscripciones. Después de todo, cualquiera puede dejar [email protected]

, y eso incluso se considerará legal, pero no es probable que sea la persona en el otro extremo.

Para PHP, debería no use el patrón dado en Validar una dirección de correo electrónico con PHP, la forma correcta de la que cito:

Existe el peligro de que el uso común y la codificación descuidada generalizada establezcan un estándar de facto para las direcciones de correo electrónico que sea más restrictivo que el estándar formal registrado.

Eso no es mejor que todos los demás patrones que no son RFC. Ni siquiera es lo suficientemente inteligente para manejar ni siquiera RFC 822, y mucho menos RFC 5322. Sin embargo, este sí lo es.

Si quiere ser elegante y pedante, implemente un motor de estado completo. Una expresión regular solo puede actuar como un filtro rudimentario. El problema con las expresiones regulares es que decirle a alguien que su dirección de correo electrónico perfectamente válida no es válida (un false positivo) porque su expresión regular no puede manejarlo es simplemente grosero y descortés desde la perspectiva del usuario. Un motor de estado para este propósito puede validar e incluso corregir direcciones de correo electrónico que de otro modo se considerarían inválidas, ya que desensambla la dirección de correo electrónico de acuerdo con cada RFC. Esto permite una experiencia potencialmente más placentera, como

La dirección de correo electrónico especificada ‘[email protected], com ‘no es válido. Querías decir ‘[email protected]’?

Consulte también Validación de direcciones de correo electrónico, incluidos los comentarios. O comparar direcciones de correo electrónico validando expresiones regulares.

Visualización de expresiones regulares

Demostración de Debuggex

No debe utilizar expresiones regulares para validar direcciones de correo electrónico.

En su lugar, use la clase MailAddress, así:

try 
    address = new MailAddress(address).Address;
 catch(FormatException) 
    // address is invalid

los MailAddress La clase utiliza un analizador BNF para validar la dirección en total conformidad con RFC822.

Si planea usar el MailAddress Para validar la dirección de correo electrónico, tenga en cuenta que este enfoque también acepta la parte del nombre para mostrar de la dirección de correo electrónico, y es posible que eso no sea exactamente lo que desea lograr. Por ejemplo, acepta estas cadenas como direcciones de correo electrónico válidas:

  • “[email protected]; [email protected]”
  • “[email protected]; [email protected]; [email protected]”
  • “Nombre de visualización del usuario [email protected]”
  • “usuario4 @ empresa.com”

En algunos de estos casos, solo la última parte de las cadenas se analiza como dirección; el resto antes de eso es el nombre para mostrar. Para obtener una dirección de correo electrónico simple sin ningún nombre para mostrar, puede comparar la dirección normalizada con su original. string.

bool isValid = false;

try

    MailAddress address = new MailAddress(emailAddress);
    isValid = (address.Address == emailAddress);
    // or
    // isValid = string.IsNullOrEmpty(address.DisplayName);

catch (FormatException)

    // address is invalid

Además, una dirección que tenga un punto al final, como [email protected] MailAddress también acepta.

Si realmente desea usar una expresión regular, aquí está:

(?:(?:rn)?[ t])*(?:(?:(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t]
)+|Z|(?=[["()<>@,;:\".[]]))|"(?:[^"r\]|\.|(?:(?:rn)?[ t]))*"(?:(?:
rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(
?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|"(?:[^"r\]|\.|(?:(?:rn)?[ 
t]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-
31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|[([^[]r\]|\.)*
](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+
(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|[([^[]r\]|\.)*](?:
(?:rn)?[ t])*))*|(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z
|(?=[["()<>@,;:\".[]]))|"(?:[^"r\]|\.|(?:(?:rn)?[ t]))*"(?:(?:rn)
?[ t])*)*<(?:(?:rn)?[ t])*(?:@(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:
rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[
 t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)
?[ t])+|Z|(?=[["()<>@,;:\".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t]
)*))*(?:,@(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[
 t])+|Z|(?=[["()<>@,;:\".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*
)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t]
)+|Z|(?=[["()<>@,;:\".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*))*)
*:(?:(?:rn)?[ t])*)?(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+
|Z|(?=[["()<>@,;:\".[]]))|"(?:[^"r\]|\.|(?:(?:rn)?[ t]))*"(?:(?:r
n)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:
rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|"(?:[^"r\]|\.|(?:(?:rn)?[ t
]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31
]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|[([^[]r\]|\.)*](
?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?
:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|[([^[]r\]|\.)*](?:(?
:rn)?[ t])*))*>(?:(?:rn)?[ t])*)|(?:[^()<>@,;:\".[] 00-31]+(?:(?
:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|"(?:[^"r\]|\.|(?:(?:rn)?
[ t]))*"(?:(?:rn)?[ t])*)*:(?:(?:rn)?[ t])*(?:(?:(?:[^()<>@,;:\".[] 
00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|"(?:[^"r\]|
\.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>

@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|"
(?:[^"r\]|\.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t]
)*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\
".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?
:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[
]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*))*|(?:[^()<>@,;:\".[] 00-
31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|"(?:[^"r\]|\.|(
?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)*<(?:(?:rn)?[ t])*(?:@(?:[^()<>@,;
:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|[([
^[]r\]|\.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:\"
.[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|[([^[
]r\]|\.)*](?:(?:rn)?[ t])*))*(?:,@(?:(?:rn)?[ t])*(?:[^()<>@,;:\".
[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|[([^[]
r\]|\.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 
00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|[([^[]r\]
|\.)*](?:(?:rn)?[ t])*))*)*:(?:(?:rn)?[ t])*)?(?:[^()<>@,;:\".[] 
00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|"(?:[^"r\]|\
.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,
;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]]))|"(?
:[^"r\]|\.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*
(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".
[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[
^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[]
]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*))*>(?:(?:rn)?[ t])*)(?:,s*(
?:(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\
".[]]))|"(?:[^"r\]|\.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(
?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[
["()<>@,;:\".[]]))|"(?:[^"r\]|\.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t
])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t
])+|Z|(?=[["()<>@,;:\".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*)(?
:.(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|
Z|(?=[["()<>@,;:\".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*))*|(?:
[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".[
]]))|"(?:[^"r\]|\.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)*<(?:(?:rn)
?[ t])*(?:@(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["
()<>@,;:\".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)
?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>

@,;:\".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*))*(?:,@(?:(?:rn)?[
 t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,
;:\".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t]
)*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\
".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*))*)*:(?:(?:rn)?[ t])*)?
(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:\".
[]]))|"(?:[^"r\]|\.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(?:
rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[[
"()<>@,;:\".[]]))|"(?:[^"r\]|\.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])
*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])
+|Z|(?=[["()<>@,;:\".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*)(?:
.(?:(?:rn)?[ t])*(?:[^()<>@,;:\".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z
|(?=[["()<>@,;:\".[]]))|[([^[]r\]|\.)*](?:(?:rn)?[ t])*))*>(?:(
?:rn)?[ t])*))*)?;s*)

Esta pregunta se hace mucho, pero creo que debería dar un paso atrás y preguntarse por qué ¿Quiere validar sintácticamente las direcciones de correo electrónico? ¿Cuál es realmente el beneficio?

  • No detectará errores tipográficos comunes.
  • No evita que las personas ingresen direcciones de correo electrónico inválidas o inventadas, o que ingresen la dirección de otra persona.

Si desea validar que un correo electrónico es correcto, no tiene más remedio que enviar un correo electrónico de confirmación y hacer que el usuario responda. En muchos casos tengo enviar un correo de confirmación de todos modos por razones de seguridad o por razones éticas (para que no pueda, por ejemplo, inscribir a alguien en un servicio en contra de su voluntad).

Puedes confirmar nuestro ensayo fijando un comentario y dejando una puntuación te damos las gracias.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *