A lo largo de los años, he desarrollado lentamente una expresión regular que valida la mayoría de las direcciones de correo electrónico correctamente, suponiendo que no usen una dirección IP como parte del servidor.
Lo uso en varios programas PHP y funciona la mayor parte del tiempo. Sin embargo, de vez en cuando me contacta alguien que tiene problemas con un sitio que lo usa, y termino teniendo que hacer algunos ajustes (más recientemente me di cuenta de que no estaba permitiendo TLD de 4 caracteres).
¿Cuál es la mejor expresión regular que tiene o ha visto para validar correos electrónicos?
He visto varias soluciones que usan funciones que usan varias expresiones más cortas, pero prefiero tener una expresión larga y compleja en una función simple en lugar de varias expresiones cortas en una función más compleja.
fuente
Respuestas:
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 las 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 el 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
cualquiera de los valores decimales de byte sin signo en un dirección delimitada por puntos, que es ilegal. El resto parece ser coherente con la gramática RFC 5322 y pasa varias pruebas usandogrep -Po
, incluidos los casos nombres de dominio, direcciones IP, incorrectos y nombres de cuenta con y sin comillas.Al corregir el
00
error en el patrón de IP, obtenemos una expresión regular que funciona y bastante rápido. (Raspe la versión renderizada, no la rebaja, para el código real).o:
Aquí hay un diagrama de la máquina de estados finitos para la expresión regular anterior que es más clara que la propia expresión regular
Los patrones más sofisticados en Perl y PCRE (biblioteca de expresiones regulares usadas, por ejemplo, en PHP) pueden analizar correctamente RFC 5322 sin problemas . Python y C # también pueden hacer eso, pero usan una sintaxis diferente de las dos primeras. Sin embargo, si se ve obligado a usar uno de los muchos lenguajes de coincidencia de patrones menos potentes, entonces es mejor usar un analizador real.
También es importante comprender que validarlo según el RFC no le dice absolutamente nada acerca de si esa dirección realmente existe en el dominio suministrado, o si la persona que ingresa la dirección es su verdadero propietario. Las personas inscriben a otros en las listas de correo de esta manera todo el tiempo. Una corrección que 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 destinado a ser ingresado en la misma página web que la dirección.
Los tokens de confirmación son la única forma de saber que recibió la dirección de la persona que lo ingresó. Es por eso que la mayoría de las listas de correo ahora usan ese mecanismo para confirmar las suscripciones. Después de todo, cualquiera puede menospreciar
[email protected]
, y eso incluso se considerará legal, pero no es probable que sea la persona del otro lado.Para PHP, usted debe no utilizar el patrón dado en Validar una dirección de correo electrónico con PHP, de la manera correcta a partir del cual cito:
Eso no es mejor que todos los otros patrones no RFC. Ni siquiera es lo suficientemente inteligente como para manejar incluso RFC 822 , y mucho menos RFC 5322. Sin embargo, este sí lo es.
Si quieres ponerte elegante y pedante, implementa 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 falso positivo) porque su expresión regular no puede manejarlo es 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 desmonta la dirección de correo electrónico de acuerdo con cada RFC. Esto permite una experiencia potencialmente más agradable, como
Consulte también Validar direcciones de correo electrónico , incluidos los comentarios. O comparando la dirección de correo electrónico validando expresiones regulares .
Demo de Debuggex
fuente
No debe usar expresiones regulares para validar las direcciones de correo electrónico.
En su lugar, use la clase MailAddress , así:
La
MailAddress
clase utiliza un analizador BNF para validar la dirección de acuerdo con RFC822.Si planea usar
MailAddress
para validar la dirección de correo electrónico, tenga en cuenta que este enfoque acepta también la parte del nombre para mostrar de la dirección de correo electrónico, y eso puede no ser exactamente lo que desea lograr. Por ejemplo, acepta estas cadenas como direcciones de correo electrónico válidas:En algunos de estos casos, solo la última parte de las cadenas se analiza como la dirección; el resto antes de eso es el nombre para mostrar. Para obtener una dirección de correo electrónico sin nombre para mostrar, puede verificar la dirección normalizada con su cadena original.
Además,
user@company.
MailAddress también acepta una dirección que tenga un punto al final .Si realmente quieres usar una expresión regular, aquí está :
fuente
[email protected]
. No debe confiar en la validación de correo electrónico para evitar XSS.Esta pregunta se hace mucho, pero creo que deberías dar un paso atrás y preguntarte por qué quieres validar sintácticamente las direcciones de correo electrónico. ¿Cuál es el beneficio realmente?
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 que el usuario responda a eso. En muchos casos, usted tiene que enviar un correo de confirmación de todos modos por razones de seguridad o por razones éticas (por lo que no se puede por ejemplo, alguien de registro a un servicio en contra de su voluntad).
fuente
me@hotmail
, obviamente no recibirá su correo electrónico de confirmación, y luego ¿dónde están? Ya no están en su sitio y se preguntan por qué no pudieron registrarse. En realidad no, no lo están, se han olvidado por completo de ti. Sin embargo, si pudieras hacer una comprobación de cordura básica con una expresión regular mientras todavía están contigo, entonces pueden detectar ese error de inmediato y tienes un usuario feliz.[email protected]
direcciones indican un comandante en jefe muy ocupado. :)Todo depende de cuán preciso quieras ser. Para mis propósitos, donde solo estoy tratando de evitar cosas como
bob @ aol.com
(espacios en los correos electrónicos) osteve
(sin dominio) omary@aolcom
(sin período antes de .com), usoClaro, coincidirá con cosas que no son direcciones de correo electrónico válidas, pero se trata de obtener errores simples comunes.
Hay varios cambios que se pueden hacer a esa expresión regular (y algunos están en los comentarios para esta respuesta), pero es simple y fácil de entender, y es un buen primer intento.
fuente
.
está incluido en\S
.mary@aolcom
fuera basura completa . YMMV.@
señales:/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/
jsfiddle.net/b9chris/mXB96Depende de lo que quieras decir con mejor: si estás hablando de atrapar cada dirección de correo electrónico válida, utiliza lo siguiente:
( http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html ) Si está buscando algo más simple pero que atrapará las direcciones de correo electrónico más válidas, intente algo como:
EDITAR: desde el enlace:
fuente
email address
que pasen erróneamente por el segundo, pero sean atrapados por la expresión regular más larga?[ACTUALIZADO] He recopilado todo lo que sé sobre la validación de direcciones de correo electrónico aquí: http://isemail.info , que ahora no solo valida sino que también diagnostica problemas con las direcciones de correo electrónico. Estoy de acuerdo con muchos de los comentarios aquí que la validación es solo una parte de la respuesta; vea mi ensayo en http://isemail.info/about .
is_email () sigue siendo, hasta donde yo sé, el único validador que le dirá definitivamente si una cadena dada es una dirección de correo electrónico válida o no. Subí una nueva versión en http://isemail.info/
Cotejé casos de prueba de Cal Henderson, Dave Child, Phil Haack, Doug Lovell, RFC5322 y RFC 3696. 275 direcciones de prueba en total. Ejecuté todas estas pruebas contra todos los validadores gratuitos que pude encontrar.
Intentaré mantener esta página actualizada a medida que las personas mejoren sus validadores. Gracias a Cal, Michael, Dave, Paul y Phil por su ayuda y cooperación en la compilación de estas pruebas y críticas constructivas de mi propio validador .
Las personas deben ser conscientes de la errata contra RFC 3696 en particular. Tres de los ejemplos canónicos son, de hecho, direcciones no válidas. Y la longitud máxima de una dirección es de 254 o 256 caracteres, no 320.
fuente
[email protected]
ya que este código se trata de validación, no de interpretación. Si desea agregar un traductor de punycode, me complace aceptar una solicitud de extracción en github.com/dominicsayers/isemailSegún la especificación HTML5 W3C :
Contexto:
fuente
john.doe@localhost
es válido. Por supuesto, en una aplicación del mundo real (es decir, una comunidad), me gustaría que sugiera reemplazar * por +"test...."@gmail.com
es perfectamente válido según el RFC y semánticamente equivalente a[email protected]
.Es fácil en Perl 5.10 o posterior:
fuente
addrspec
parte es realmente relevante para la pregunta. Aceptar más que eso y reenviarlo a través de alguna otra parte del sistema que no está lista para aceptar direcciones RFC5822 completas es como disparar es su propio pie.yo suelo
Cuál es el utilizado en ASP.NET por el RegularExpressionValidator.
fuente
[email protected]
es rechazada.^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w{2,}([-.]\\w+)*$
[email protected]
que de hecho es válido (un cliente nuestro tenía una dirección similar) `No sé cuál es el mejor, pero este es al menos correcto, siempre y cuando las direcciones tengan sus comentarios eliminados y reemplazados por espacios en blanco.
Seriamente. Debe usar una biblioteca ya escrita para validar correos electrónicos. Probablemente, la mejor manera sea enviar un correo electrónico de verificación a esa dirección.
fuente
Las direcciones de correo electrónico que quiero validar serán utilizadas por una aplicación web ASP.NET utilizando el espacio de nombres System.Net.Mail para enviar correos electrónicos a una lista de personas. Entonces, en lugar de usar una expresión regular muy compleja, solo trato de crear una instancia de MailAddress desde la dirección. El constructor MailAddress lanzará una excepción si la dirección no se forma correctamente. De esta manera, sé que al menos puedo sacar el correo electrónico de la puerta. Por supuesto, esta es la validación del lado del servidor, pero como mínimo lo necesita de todos modos.
fuente
args.Value
lugar de hacer referencia al campo comotxtEmail.Text
codificado. El último vinculará su validador a la única instancia de control, que puede estar bien, siempre que tenga un solo campo de correo electrónico, pero no se recomienda lo contrario.Respuesta rápida
Use la siguiente expresión regular para la validación de entrada:
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+
Direcciones que coinciden con esta expresión regular:
La segunda restricción es una restricción en RFC 5321/5322.
Respuesta elaborada
El uso de una expresión regular que reconozca las direcciones de correo electrónico podría ser útil en varias situaciones: por ejemplo, para buscar direcciones de correo electrónico en un documento, para validar la entrada del usuario o como una restricción de integridad en un repositorio de datos.
Sin embargo, debe tenerse en cuenta que si desea averiguar si la dirección realmente se refiere a un buzón existente, no hay sustituto para enviar un mensaje a la dirección. Si solo desea verificar si una dirección es gramaticalmente correcta, entonces podría usar una expresión regular, pero tenga en cuenta que
""@[]
es una dirección de correo electrónico gramaticalmente correcta que ciertamente no se refiere a un buzón existente.La sintaxis de las direcciones de correo electrónico se ha definido en varios RFC , especialmente RFC 822 y RFC 5322 . RFC 822 debe verse como el estándar "original" y RFC 5322 como el último estándar. La sintaxis definida en RFC 822 es la más indulgente y los estándares posteriores han restringido la sintaxis más y más, donde los sistemas o servicios más nuevos deberían reconocer la sintaxis obsoleta, pero nunca producirla.
En esta respuesta, tomaré "dirección de correo electrónico"
addr-spec
como se define en los RFC (es decir[email protected]
, pero no"John Doe"<[email protected]>
, nisome-group:[email protected],[email protected];
).Hay un problema al traducir las sintaxis RFC en expresiones regulares: ¡las sintaxis no son regulares! Esto se debe a que permiten comentarios opcionales en las direcciones de correo electrónico que se pueden anidar infinitamente, mientras que la anidación infinita no se puede describir mediante una expresión regular. Para buscar o validar direcciones que contengan comentarios, necesita un analizador o expresiones más potentes. (Tenga en cuenta que los lenguajes como Perl tienen construcciones para describir las gramáticas libres de contexto de una manera similar a la expresión regular). En esta respuesta, ignoraré los comentarios y solo consideraré las expresiones regulares adecuadas.
Los RFC definen sintaxis para mensajes de correo electrónico, no para direcciones de correo electrónico como tales. Las direcciones pueden aparecer en varios campos de encabezado y aquí es donde se definen principalmente. Cuando aparecen en los campos de encabezado, las direcciones pueden contener (entre tokens léxicos) espacios en blanco, comentarios e incluso saltos de línea. Sin embargo, semánticamente esto no tiene importancia. Al eliminar este espacio en blanco, etc. de una dirección, obtienes una representación canónica semánticamente equivalente . Por lo tanto, la representación canónica de
first. last (comment) @ [3.5.7.9]
esfirst.last@[3.5.7.9]
.Se deben usar diferentes sintaxis para diferentes propósitos. Si desea escanear direcciones de correo electrónico en un documento (posiblemente muy antiguo), puede ser una buena idea usar la sintaxis como se define en RFC 822. Por otro lado, si desea validar la entrada del usuario, puede usar el sintaxis como se define en RFC 5322, probablemente solo acepte representaciones canónicas. Debe decidir qué sintaxis se aplica a su caso específico.
Utilizo expresiones regulares POSIX "extendidas" en esta respuesta, suponiendo un conjunto de caracteres compatible con ASCII.
RFC 822
Llegué a la siguiente expresión regular. Invito a todos a intentar romperlo. Si encuentra falsos positivos o falsos negativos, publíquelos en un comentario e intentaré corregir la expresión lo antes posible.
([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*"))*@([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*]))*
Creo que es totalmente compatible con RFC 822, incluida la errata . Solo reconoce las direcciones de correo electrónico en su forma canónica. Para una expresión regular que reconoce espacios en blanco (plegables), vea la derivación a continuación.
La derivación muestra cómo llegué a la expresión. Enumero todas las reglas gramaticales relevantes del RFC exactamente como aparecen, seguido de la expresión regular correspondiente. Cuando se ha publicado una errata, doy una expresión separada para la regla gramatical corregida (marcada "errata") y uso la versión actualizada como subexpresión en las expresiones regulares posteriores.
Como se indica en el apartado 3.1.4. de RFC 822 se puede insertar un espacio en blanco lineal opcional entre las fichas léxicas. Donde corresponda, expandí las expresiones para acomodar esta regla y marqué el resultado con "opt-lwsp".
RFC 5322
Llegué a la siguiente expresión regular. Invito a todos a intentar romperlo. Si encuentra falsos positivos o falsos negativos, publíquelos en un comentario e intentaré corregir la expresión lo antes posible.
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])
Creo que es totalmente compatible con RFC 5322, incluida la errata . Solo reconoce las direcciones de correo electrónico en su forma canónica. Para una expresión regular que reconoce espacios en blanco (plegables), vea la derivación a continuación.
La derivación muestra cómo llegué a la expresión. Enumero todas las reglas gramaticales relevantes del RFC exactamente como aparecen, seguido de la expresión regular correspondiente. Para las reglas que incluyen espacios en blanco semánticamente irrelevantes (plegables), doy una expresión regular separada marcada "(normalizada)" que no acepta este espacio en blanco.
Ignoré todas las reglas "obs-" del RFC. Esto significa que las expresiones regulares solo coinciden con las direcciones de correo electrónico que son estrictamente compatibles con RFC 5322. Si tiene que hacer coincidir las direcciones "antiguas" (como lo hace la gramática más flexible, incluidas las reglas "obs-"), puede usar una de las expresiones regulares RFC 822 del párrafo anterior.
Tenga en cuenta que algunas fuentes (especialmente w3c ) afirman que RFC 5322 es demasiado estricto en la parte local (es decir, la parte anterior al signo @). Esto se debe a que "..", "a..b" y "a". no son puntos-átomos válidos, mientras que pueden usarse como nombres de buzones. El RFC, sin embargo, no permiten partes locales como estos, excepto en que tienen que ser citado. Entonces, en lugar de
[email protected]
usted, debe escribir"a..b"@example.net
, que es semánticamente equivalente.Restricciones adicionales
SMTP (como se define en RFC 5321 ) restringe aún más el conjunto de direcciones de correo electrónico válidas (o en realidad: nombres de buzones). Parece razonable imponer esta gramática más estricta, de modo que la dirección de correo electrónico coincidente pueda usarse para enviar un correo electrónico.
RFC 5321 básicamente deja sola la parte "local" (es decir, la parte anterior al signo @), pero es más estricta en la parte del dominio (es decir, la parte posterior al signo @). Solo permite nombres de host en lugar de átomos de punto y literales de dirección en lugar de literales de dominio.
La gramática presentada en RFC 5321 es demasiado indulgente cuando se trata de nombres de host y direcciones IP. Me tomé la libertad de "corregir" las reglas en cuestión, utilizando este borrador y RFC 1034 como pautas. Aquí está la expresión regular resultante.
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)])
Tenga en cuenta que, según el caso de uso, es posible que no desee permitir un "General-address-literal" en su expresión regular. También tenga en cuenta que utilicé una búsqueda anticipada negativa
(?!IPv6:)
en la expresión regular final para evitar que la parte "General-address-literal" coincida con direcciones IPv6 mal formadas. Algunos procesadores de expresiones regulares no son compatibles con la búsqueda anticipada negativa. Elimine la subcadena|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+
de la expresión regular si desea eliminar toda la parte "General-address-literal".Aquí está la derivación:
Validación de entrada del usuario
Un caso de uso común es la validación de entrada del usuario, por ejemplo en un formulario html. En ese caso, generalmente es razonable excluir literales de dirección y requerir al menos dos etiquetas en el nombre de host. Tomando como base la expresión regular RFC 5321 mejorada de la sección anterior, la expresión resultante sería:
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+
No recomiendo restringir aún más la parte local, por ejemplo, excluyendo las cadenas entre comillas, ya que no sabemos qué tipo de nombres de buzones permiten algunos hosts (como
"a..b"@example.net
o incluso"a b"@example.net
).Tampoco recomiendo validar explícitamente contra una lista de dominios literales de nivel superior o incluso imponer restricciones de longitud (recuerde cómo invalida ".museum"
[a-z]{2,4}
), pero si debe:([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?\.)*(net|org|com|info|
etc ...)
Asegúrese de mantener su expresión regular actualizada si decide seguir el camino de la validación explícita del dominio de nivel superior.
Consideraciones adicionales
Cuando solo se aceptan nombres de host en la parte del dominio (después del signo @), las expresiones regulares anteriores solo aceptan etiquetas con un máximo de 63 caracteres, como deberían. Sin embargo, no imponen el hecho de que el nombre completo del host debe tener como máximo 253 caracteres (incluidos los puntos). Aunque esta restricción estrictamente hablando sigue siendo regular, no es factible hacer una expresión regular que incorpore esta regla.
Otra consideración, especialmente cuando se usan expresiones regulares para la validación de entrada, es la retroalimentación al usuario. Si un usuario ingresa una dirección incorrecta, sería bueno dar un poco más de comentarios que una simple "dirección sintácticamente incorrecta". Con expresiones regulares "vainilla" esto no es posible.
Estas dos consideraciones podrían abordarse analizando la dirección. En algunos casos, la restricción de longitud adicional en los nombres de host también podría abordarse mediante el uso de una expresión regular adicional que lo verifique y que coincida la dirección con ambas expresiones.
Ninguna de las expresiones regulares en esta respuesta está optimizada para el rendimiento. Si el rendimiento es un problema, debería ver si (y cómo) se puede optimizar la expresión regular de su elección.
fuente
arbitrary-long-email-address-should-be-invalid-arbitrary-long-email-address-should-be-invalid.and-the-second-group-also-should-not-be-so-long-and-the-second-group-also-should-not-be-so-long@example.com
no debe validar. Sugiero cambiar los signos "+" en el primer grupo (nombre antes del punto opcional) y en el segundo grupo (nombre después de los siguientes puntos) a{1,64}
$emailRegex = '/^([-!#-\'*+\/-9=?A-Z^-~]{1,64}(\.[-!#-\'*+\/-9=?A-Z^-~]{1,64})*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+$/';
Hay muchos ejemplos de esto en la red (y creo que incluso uno que valida completamente el RFC, pero tiene decenas / cientos de líneas de largo si la memoria sirve). La gente tiende a dejarse llevar por la validación de este tipo de cosas. ¿Por qué no simplemente verificar que tiene una @ y al menos una? y cumple con una longitud mínima simple. Es trivial ingresar un correo electrónico falso y aun así coincidir con cualquier expresión regular válida. Supongo que los falsos positivos son mejores que los falsos negativos.
fuente
Al decidir qué caracteres están permitidos, recuerde a sus amigos apostrofeados y con guiones. No tengo control sobre el hecho de que mi empresa genera mi dirección de correo electrónico utilizando mi nombre del sistema de recursos humanos. Eso incluye el apóstrofe en mi apellido. No puedo decirle cuántas veces me han bloqueado la interacción con un sitio web por el hecho de que mi dirección de correo electrónico es "no válida".
fuente
Esta expresión regular es de la biblioteca Email :: Valid de Perl . Creo que es el más preciso, coincide con los 822. Y se basa en la expresión regular del libro de O'Reilly:
fuente
Mientras escribe en PHP, le aconsejo que use la validación integrada de PHP para correos electrónicos.
Si está ejecutando una versión php inferior a 5.3.6, tenga en cuenta este problema: https://bugs.php.net/bug.php?id=53091
Si desea obtener más información sobre cómo funciona esta validación integrada , consulte aquí: ¿Funciona realmente filter_var FILTER_VALIDATE_EMAIL de PHP?
fuente
Cal Henderson (Flickr) escribió un artículo llamado Analizar direcciones de correo electrónico en PHP y muestra cómo hacer un análisis de direcciones de correo electrónico que cumpla con RFC (2) 822. También puede obtener el código fuente en php , python y ruby que tiene licencia cc .
fuente
a@b
era válidoa@b
es válido ... en este casob
es el dominio de nivel superior.Nunca me molesto en crear con mi propia expresión regular, porque lo más probable es que otra persona ya haya encontrado una versión mejor. Siempre uso regexlib para encontrar uno de mi agrado.
fuente
No hay uno que sea realmente utilizable.
Discuto algunos problemas en mi respuesta a ¿Hay una biblioteca php para la validación de la dirección de correo electrónico? , se discute también en Regexp reconocimiento de dirección de correo electrónico duro?
En resumen, no espere que una expresión regular utilizable haga un trabajo adecuado. Y la mejor expresión regular validará la sintaxis, no la validez de un correo electrónico ([email protected] es correcto pero probablemente rebotará ...).
fuente
Una expresión regular simple que al menos no rechazaría una dirección de correo electrónico válida sería buscar algo, seguido de un signo @ y luego algo seguido de un punto y al menos 2 cosas. No rechazará nada, pero después de revisar las especificaciones no puedo encontrar ningún correo electrónico que sea válido y rechazado.
correo electrónico = ~
/.+@[^@]+\.[^@]{2,}$/
fuente
/^[^@]+@[^@]+\.[^@]{2}[^@]*$/
en realidad comprueba el signo 1 @. Su expresión regular dejará pasar múltiples debido a. * Al final./^[^@]+@[^@]+\.[^@]{2,4}$/
asegurándose de que termine con 2 a 4 caracteres que no sean @. Como señaló @Josh, ahora permite una @ extra al final. Pero también puede cambiar eso a:/^[^@]+@[^@]+\.[^a-z-A-Z]{2,4}$/
ya que todos los dominios de nivel superior son caracteres aZ. puede reemplazar4
con5
o más permitiendo que los nombres de dominio de nivel superior sean más largos en el futuro también.Puede usar el empleado por el complemento de validación jQuery:
fuente
a-b'[email protected]
pero pudo detectar variaciones inapropiadas, comoa-b'[email protected]
ya-b'[email protected]
Para obtener la evaluación más completa de la mejor expresión regular para validar una dirección de correo electrónico, consulte este enlace; " Comparación de la dirección de correo electrónico que valida expresiones regulares "
Aquí está la expresión superior actual para fines de referencia:
fuente
Sin mencionar que los nombres de dominio no latinos (chino, árabe, griego, hebreo, cirílico, etc.) se permitirán en un futuro próximo . Todos tienen que cambiar la expresión regular del correo electrónico utilizada, porque esos caracteres seguramente no serán cubiertos por
[a-z]/i
ni\w
. Todos fallarán.Después de todo, la mejor manera de validar la dirección de correo electrónico es enviar un correo electrónico a la dirección en cuestión para validar la dirección. Si la dirección de correo electrónico es parte de la autenticación del usuario (registro / inicio de sesión / etc.), puede combinarla perfectamente con el sistema de activación del usuario. Es decir, enviar un correo electrónico con un enlace con una clave de activación única a la dirección de correo electrónico especificada y solo permitir el inicio de sesión cuando el usuario haya activado la cuenta recién creada usando el enlace en el correo electrónico.
Si el propósito de la expresión regular es solo informar rápidamente al usuario en la interfaz de usuario que la dirección de correo electrónico especificada no se ve en el formato correcto, lo mejor es verificar si coincide básicamente con la siguiente expresión regular:
Simple como eso. ¿Por qué te importarían los caracteres utilizados en el nombre y el dominio? Es responsabilidad del cliente ingresar una dirección de correo electrónico válida, no la del servidor. Incluso cuando el cliente ingresa una dirección de correo electrónico sintácticamente válida como
[email protected]
, esto no garantiza que sea una dirección de correo electrónico legítima. Nadie regex puede cubrir eso.fuente
spaces
después de@.
eg.[email protected] com net
se considera un correo electrónico válido mediante el uso de la expresión regular anterior donde, como debería ser, devuelve no válido.La especificación HTML5 sugiere una expresión regular simple para validar direcciones de correo electrónico:
Esto intencionalmente no cumple con RFC 5322 .
La longitud total también podría limitarse a 254 caracteres, según la errata RFC 3696 1690 .
fuente
invalid@emailaddress
. ¡Instaría precaución y muchas pruebas antes de usarlo!Para una demostración vívida, el siguiente monstruo es bastante bueno pero todavía no reconoce correctamente todas las direcciones de correo electrónico sintácticamente válidas: reconoce comentarios anidados de hasta cuatro niveles de profundidad.
Este es un trabajo para un analizador sintáctico, pero incluso si una dirección es sintácticamente válida, es posible que aún no se pueda entregar. A veces tienes que recurrir al método hillbilly de "¡Hola, todos, mírennos!"
fuente
De acuerdo con el estándar oficial RFC 2822, la expresión regular de correo electrónico válida es
si quieres usarlo en Java es realmente muy fácil
fuente
(?:[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
Aquí está el PHP que uso. Elegí esta solución en el espíritu de "los falsos positivos son mejores que los falsos negativos", según lo declarado por otro comentarista aquí Y con respecto a mantener el tiempo de respuesta y la carga del servidor ... realmente no hay necesidad de desperdiciar recursos del servidor con una expresión regular cuando esto eliminará el error de usuario más simple. Siempre puede seguir esto enviando un correo electrónico de prueba si lo desea.
fuente
RFC 5322 estándar:
Permite la parte local del átomo de punto, la parte local de la cadena entre comillas, la parte local obsoleta (átomo de punto mixto y la cadena entre comillas), el dominio de nombre de dominio, (IPv4, IPv6 y la dirección IPv6 asignada a IPv4) dominio literal, y (anidados) CFWS.
RFC 5321 estándar:
Permite la parte local de átomo de punto, la parte local de cadena de comillas, el dominio de nombre de dominio y el dominio literal de dominio (IPv4, IPv6 y dirección IPv6 asignada a IPv4).
Básico:
Permite la parte local de átomo de punto y el dominio de nombre de dominio (que requiere al menos dos etiquetas de nombre de dominio con el TLD limitado a 2-6 caracteres alfabéticos).
fuente
/D
bandera y la ha citado con comillas simples pero también ha usado barras para delimitar el patrón? No es Perl, y no puede ser PCRE. ¿Es por lo tanto PHP? Creo que esos son los únicos tres que permiten la recursividad(?1)
.Es extraño que "no pueda" permitir TLD de 4 caracteres. Está prohibiendo a las personas de .info y .name , y la limitación de longitud detiene .travel y .museum , pero sí, son menos comunes que los TLD de 2 caracteres y los TLD de 3 caracteres.
También debe permitir alfabetos en mayúsculas. Los sistemas de correo electrónico normalizarán la parte local y la parte de dominio.
Para su expresión regular de la parte de dominio, el nombre de dominio no puede comenzar con '-' y no puede terminar con '-'. Dash solo puede permanecer en el medio.
Si usó la biblioteca PEAR, consulte su función de correo (olvidó el nombre / biblioteca exactos). Puede validar la dirección de correo electrónico llamando a una función, y valida la dirección de correo electrónico de acuerdo con la definición en RFC822.
fuente
fuente