test solo regulares regular probar letras expresiones expresion espacios espacio ejemplos blanco alfanumerico regex email email-validation string-parsing

regex - solo - probar expresiones regulares



Usar una expresión regular para validar una dirección de correo electrónico (30)

A lo largo de los años he desarrollado lentamente una expresión regular que valida las direcciones de correo electrónico MOST correctamente, suponiendo que no utilicen 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 algún ajuste (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.


Respuesta rápida

Use la siguiente expresión regular para la validación de entrada:

([-!#-''*+/-9=?AZ^-~]+(/.[-!#-''*+/-9=?AZ^-~]+)*|"([]!#-[^-~ /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 coincidentes con esta expresión regular:

  • tener una parte local (es decir, la parte anterior al @ -sign) que cumpla estrictamente con RFC 5321/5322,
  • tener una parte de dominio (es decir, la parte después del @ -sign) que es un nombre de host con al menos dos etiquetas, cada una de las cuales tiene un máximo de 63 caracteres.

La segunda restricción es una restricción en RFC 5321/5322.

Respuesta elaborada

Usar una expresión regular que reconozca las direcciones de correo electrónico podría ser útil en diversas situaciones: por ejemplo, para buscar direcciones de correo electrónico en un documento, validar la entrada del usuario o como una restricción de integridad en un depósito de datos.

Sin embargo, debe tenerse en cuenta que si desea averiguar si la dirección se refiere realmente 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, 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 varias RFC , principalmente 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 cada vez más, donde los sistemas o servicios más nuevos deberían reconocer la sintaxis obsoleta, pero nunca la deben producir.

En esta respuesta, tomaré "dirección de correo electrónico" para que signifique addr-spec como se define en las RFC (es decir, [email protected] , pero no "John Doe"<[email protected]> , ni some-group:[email protected],[email protected]; ).

Hay un problema al traducir las sintaxis de RFC en expresiones regulares: ¡las sintaxis no son regulares! Esto se debe a que permiten comentarios opcionales en direcciones de correo electrónico que pueden anidarse infinitamente, mientras que la anidación infinita no puede describirse mediante una expresión regular. Para buscar o validar direcciones que contienen comentarios, necesita un analizador o expresiones más potentes. (Tenga en cuenta que los lenguajes como Perl tienen construcciones para describir gramáticas libres de contexto de forma similar a la expresión regular). En esta respuesta, dejaré de lado los comentarios y solo consideraré las expresiones regulares correctas.

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 campos de encabezado, las direcciones pueden contener (entre tokens léxicos) espacios en blanco, comentarios e incluso saltos de línea. Semánticamente, esto no tiene importancia, sin embargo. Al eliminar este espacio en blanco, etc. de una dirección, obtiene una representación canónica semánticamente equivalente. Por lo tanto, la representación canónica de first. last (comment) @ [3.5.7.9] first. last (comment) @ [3.5.7.9] es first.last@[3.5.7.9] .

Diferentes sintaxis deberían usarse para diferentes propósitos. Si desea escanear direcciones de correo electrónico en un documento (posiblemente muy antiguo), puede ser una buena idea utilizar la sintaxis tal como se define en RFC 822. Por otro lado, si desea validar la entrada del usuario, es posible que desee utilizar el sintaxis como se define en RFC 5322, probablemente solo aceptando representaciones canónicas. Debe decidir qué sintaxis se aplica a su caso específico.

Uso expresiones regulares "extendidas" de POSIX en esta respuesta, asumiendo un juego 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 y trataré de 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 (plegables) espacios en blanco, consulte la derivación a continuación.

La derivación muestra cómo llegué a la expresión. Enumero todas las reglas gramaticales relevantes de la RFC exactamente como aparecen, seguidas de la expresión regular correspondiente. Cuando una errata ha sido publicado Doy una expresión separada para la regla gramatical corregido (marcado "fe de erratas") y utilizar la versión actualizada como una subexpresión en expresiones regulares posteriores.

Como se indica en el párrafo 3.1.4. de RFC 822 opcional espacio en blanco lineal puede ser insertado entre tokens léxicos. En su caso he ampliado las expresiones para dar cabida a esta regla y marcado con el resultado "opt-LWSP".

CHAR = <any ASCII character> =~ . CTL = <any ASCII control character and DEL> =~ [/x00-/x1F/x7F] CR = <ASCII CR, carriage return> =~ /r LF = <ASCII LF, linefeed> =~ /n SPACE = <ASCII SP, space> =~ HTAB = <ASCII HT, horizontal-tab> =~ /t <"> = <ASCII quote mark> =~ " CRLF = CR LF =~ /r/n LWSP-char = SPACE / HTAB =~ [ /t] linear-white-space = 1*([CRLF] LWSP-char) =~ ((/r/n)?[ /t])+ specials = "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "/" / <"> / "." / "[" / "]" =~ [][()<>@,;://".] quoted-pair = "/" CHAR =~ //. qtext = <any CHAR excepting <">, "/" & CR, and including linear-white-space> =~ [^"///r]|((/r/n)?[ /t])+ dtext = <any CHAR excluding "[", "]", "/" & CR, & including linear-white-space> =~ [^][///r]|((/r/n)?[ /t])+ quoted-string = <"> *(qtext|quoted-pair) <"> =~ "([^"///r]|((/r/n)?[ /t])|//.)*" (erratum) =~ "(/n|(///r)*([^"///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*" domain-literal = "[" *(dtext|quoted-pair) "]" =~ /[([^][///r]|((/r/n)?[ /t])|//.)*] (erratum) =~ /[(/n|(///r)*([^][///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*] atom = 1*<any CHAR except specials, SPACE and CTLs> =~ [^][()<>@,;://". /x00-/x1F/x7F]+ word = atom / quoted-string =~ [^][()<>@,;://". /x00-/x1F/x7F]+|"(/n|(///r)*([^"///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*" domain-ref = atom sub-domain = domain-ref / domain-literal =~ [^][()<>@,;://". /x00-/x1F/x7F]+|/[(/n|(///r)*([^][///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*] local-part = word *("." word) =~ ([^][()<>@,;://". /x00-/x1F/x7F]+|"(/n|(///r)*([^"///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*")(/.([^][()<>@,;://". /x00-/x1F/x7F]+|"(/n|(///r)*([^"///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*"))* (opt-lwsp) =~ ([^][()<>@,;://". /x00-/x1F/x7F]+|"(/n|(///r)*([^"///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*")(((/r/n)?[ /t])*/.((/r/n)?[ /t])*([^][()<>@,;://". /x00-/x1F/x7F]+|"(/n|(///r)*([^"///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*"))* domain = sub-domain *("." sub-domain) =~ ([^][()<>@,;://". /x00-/x1F/x7F]+|/[(/n|(///r)*([^][///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*])(/.([^][()<>@,;://". /x00-/x1F/x7F]+|/[(/n|(///r)*([^][///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*]))* (opt-lwsp) =~ ([^][()<>@,;://". /x00-/x1F/x7F]+|/[(/n|(///r)*([^][///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*])(((/r/n)?[ /t])*/.((/r/n)?[ /t])*([^][()<>@,;://". /x00-/x1F/x7F]+|/[(/n|(///r)*([^][///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*]))* addr-spec = local-part "@" domain =~ ([^][()<>@,;://". /x00-/x1F/x7F]+|"(/n|(///r)*([^"///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*")(/.([^][()<>@,;://". /x00-/x1F/x7F]+|"(/n|(///r)*([^"///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*"))*@([^][()<>@,;://". /x00-/x1F/x7F]+|/[(/n|(///r)*([^][///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*])(/.([^][()<>@,;://". /x00-/x1F/x7F]+|/[(/n|(///r)*([^][///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*]))* (opt-lwsp) =~ ([^][()<>@,;://". /x00-/x1F/x7F]+|"(/n|(///r)*([^"///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*")((/r/n)?[ /t])*(/.((/r/n)?[ /t])*([^][()<>@,;://". /x00-/x1F/x7F]+|"(/n|(///r)*([^"///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*")((/r/n)?[ /t])*)*@((/r/n)?[ /t])*([^][()<>@,;://". /x00-/x1F/x7F]+|/[(/n|(///r)*([^][///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*])(((/r/n)?[ /t])*/.((/r/n)?[ /t])*([^][()<>@,;://". /x00-/x1F/x7F]+|/[(/n|(///r)*([^][///r/n]|//[^/r]|(/r/n)?[ /t]))*(///r)*]))* (canonical) =~ ([^][()<>@,;://". /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)*]))*

RFC 5322

Llegué a la siguiente expresión regular. Invito a todos a tratar de romperlo. Si encuentra algún falsos positivos o falsos negativos, por favor publicarlos en un comentario y voy a tratar de corregir la expresión tan pronto como sea posible.

([-!#-''*+/-9=?AZ^-~]+(/.[-!#-''*+/-9=?AZ^-~]+)*|"([]!#-[^-~ /t]|(//[/t -~]))+")@([-!#-''*+/-9=?AZ^-~]+(/.[-!#-''*+/-9=?AZ^-~]+)*|/[[/t -Z^-~]*])

Creo que es totalmente complient con la RFC 5322 que incluye la fe de erratas . Sólo se reconoce direcciones de correo electrónico en su forma canónica. Para una expresión regular que reconoce (plegable) espacios en blanco ver la derivación a continuación.

La derivación muestra cómo llegué a la expresión. Enumero todas las reglas gramaticales relevantes desde el RFC exactamente como aparecen, seguidos de la expresión regular correspondiente. Para las reglas que incluyen espacios en blanco (plegable) semánticamente irrelevante, Doy una expresión regular separada marcado "(normalizado)" que no acepta este espacio en blanco.

Ignoré todas las reglas "Obs-" de la RFC. Esto significa que las expresiones regulares sólo se ajustan a direcciones de correo electrónico que son estrictamente RFC 5322 compatible. Si usted tiene que coincidir con las direcciones de los "viejos" (como la gramática más flexible que incluye las reglas "Obs-" lo hace), puede utilizar una de las expresiones regulares RFC 822 del párrafo anterior.

VCHAR = %x21-7E =~ [!-~] ALPHA = %x41-5A / %x61-7A =~ [A-Za-z] DIGIT = %x30-39 =~ [0-9] HTAB = %x09 =~ /t CR = %x0D =~ /r LF = %x0A =~ /n SP = %x20 =~ DQUOTE = %x22 =~ " CRLF = CR LF =~ /r/n WSP = SP / HTAB =~ [/t ] quoted-pair = "/" (VCHAR / WSP) =~ //[/t -~] FWS = ([*WSP CRLF] 1*WSP) =~ ([/t ]*/r/n)?[/t ]+ ctext = %d33-39 / %d42-91 / %d93-126 =~ []!-''*-[^-~] ("comment" is left out in the regex) ccontent = ctext / quoted-pair / comment =~ []!-''*-[^-~]|(//[/t -~]) (not regular) comment = "(" *([FWS] ccontent) [FWS] ")" (is equivalent to FWS when leaving out comments) CFWS = (1*([FWS] comment) [FWS]) / FWS =~ ([/t ]*/r/n)?[/t ]+ atext = ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "''" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~" =~ [-!#-''*+/-9=?A-Z^-~] dot-atom-text = 1*atext *("." 1*atext) =~ [-!#-''*+/-9=?A-Z^-~]+(/.[-!#-''*+/-9=?A-Z^-~]+)* dot-atom = [CFWS] dot-atom-text [CFWS] =~ (([/t ]*/r/n)?[/t ]+)?[-!#-''*+/-9=?A-Z^-~]+(/.[-!#-''*+/-9=?A-Z^-~]+)*(([/t ]*/r/n)?[/t ]+)? (normalized) =~ [-!#-''*+/-9=?A-Z^-~]+(/.[-!#-''*+/-9=?A-Z^-~]+)* qtext = %d33 / %d35-91 / %d93-126 =~ []!#-[^-~] qcontent = qtext / quoted-pair =~ []!#-[^-~]|(//[/t -~]) (erratum) quoted-string = [CFWS] DQUOTE ((1*([FWS] qcontent) [FWS]) / FWS) DQUOTE [CFWS] =~ (([/t ]*/r/n)?[/t ]+)?"(((([/t ]*/r/n)?[/t ]+)?([]!#-[^-~]|(//[/t -~])))+(([/t ]*/r/n)?[/t ]+)?|(([/t ]*/r/n)?[/t ]+)?)"(([/t ]*/r/n)?[/t ]+)? (normalized) =~ "([]!#-[^-~ /t]|(//[/t -~]))+" dtext = %d33-90 / %d94-126 =~ [!-Z^-~] domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS] =~ (([/t ]*/r/n)?[/t ]+)?/[((([/t ]*/r/n)?[/t ]+)?[!-Z^-~])*(([/t ]*/r/n)?[/t ]+)?](([/t ]*/r/n)?[/t ]+)? (normalized) =~ /[[/t -Z^-~]*] local-part = dot-atom / quoted-string =~ (([/t ]*/r/n)?[/t ]+)?[-!#-''*+/-9=?A-Z^-~]+(/.[-!#-''*+/-9=?A-Z^-~]+)*(([/t ]*/r/n)?[/t ]+)?|(([/t ]*/r/n)?[/t ]+)?"(((([/t ]*/r/n)?[/t ]+)?([]!#-[^-~]|(//[/t -~])))+(([/t ]*/r/n)?[/t ]+)?|(([/t ]*/r/n)?[/t ]+)?)"(([/t ]*/r/n)?[/t ]+)? (normalized) =~ [-!#-''*+/-9=?A-Z^-~]+(/.[-!#-''*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ /t]|(//[/t -~]))+" domain = dot-atom / domain-literal =~ (([/t ]*/r/n)?[/t ]+)?[-!#-''*+/-9=?A-Z^-~]+(/.[-!#-''*+/-9=?A-Z^-~]+)*(([/t ]*/r/n)?[/t ]+)?|(([/t ]*/r/n)?[/t ]+)?/[((([/t ]*/r/n)?[/t ]+)?[!-Z^-~])*(([/t ]*/r/n)?[/t ]+)?](([/t ]*/r/n)?[/t ]+)? (normalized) =~ [-!#-''*+/-9=?A-Z^-~]+(/.[-!#-''*+/-9=?A-Z^-~]+)*|/[[/t -Z^-~]*] addr-spec = local-part "@" domain =~ ((([/t ]*/r/n)?[/t ]+)?[-!#-''*+/-9=?A-Z^-~]+(/.[-!#-''*+/-9=?A-Z^-~]+)*(([/t ]*/r/n)?[/t ]+)?|(([/t ]*/r/n)?[/t ]+)?"(((([/t ]*/r/n)?[/t ]+)?([]!#-[^-~]|(//[/t -~])))+(([/t ]*/r/n)?[/t ]+)?|(([/t ]*/r/n)?[/t ]+)?)"(([/t ]*/r/n)?[/t ]+)?)@((([/t ]*/r/n)?[/t ]+)?[-!#-''*+/-9=?A-Z^-~]+(/.[-!#-''*+/-9=?A-Z^-~]+)*(([/t ]*/r/n)?[/t ]+)?|(([/t ]*/r/n)?[/t ]+)?/[((([/t ]*/r/n)?[/t ]+)?[!-Z^-~])*(([/t ]*/r/n)?[/t ]+)?](([/t ]*/r/n)?[/t ]+)?) (normalized) =~ ([-!#-''*+/-9=?A-Z^-~]+(/.[-!#-''*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ /t]|(//[/t -~]))+")@([-!#-''*+/-9=?A-Z^-~]+(/.[-!#-''*+/-9=?A-Z^-~]+)*|/[[/t -Z^-~]*])

Tenga en cuenta que algunas fuentes (sobre todo W3C ) afirman que el RFC 5322 es demasiado estricto en la parte local (es decir, la parte antes del signo @). Esto se debe a que "..", "a..b" y "a". son no válidos punto-átomos, mientras que pueden ser utilizados como nombres de buzón. El RFC, sin embargo, no permiten partes locales como estos, excepto en que tienen que ser citado. Así que en lugar de [email protected]que usted debe escribir "a..b"@example.net, que es semánticamente equivalente.

otras restricciones

SMTP (como se define en el RFC 5321 ) restringe aún más el conjunto de direcciones válidas de correo electrónico (o en realidad: los nombres de buzón). Parece razonable imponer esta gramática más estricta, por lo que la dirección de correo electrónico emparejado en realidad se puede utilizar para enviar un correo electrónico.

RFC 5321, básicamente, deja solo la parte "local" (es decir, la parte antes del signo @), pero es más estricta en la parte del dominio (es decir, la parte que sigue al signo @). Se permite que sólo los nombres de host en lugar de punto-átomos y literales de direcciones en lugar de literales de dominio.

La gramática se presenta en el RFC 5321 es demasiado indulgente cuando se trata de los dos nombres de host y direcciones IP. Me tomé la libertad de "corregir" las normas en cuestión, mediante este proyecto y RFC 1034 como directrices. Aquí está la expresión regular resultante.

([-!#-''*+/-9=?AZ^-~]+(/.[-!#-''*+/-9=?AZ^-~]+)*|"([]!#-[^-~ /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 dependiendo del caso de uso puede que no desee para permitir una "General-Dirección-literal" en su expresión regular. También tenga en cuenta que he usado una búsqueda negativa hacia delante (?!IPv6:)en la expresión regular final para evitar que la parte "General-Dirección-literal" para que coincida con las direcciones IPv6 malformados. Algunos procesadores de expresiones regulares no son compatibles con búsqueda negativa hacia delante. Retire la subcadena |(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+de la expresión regular si usted quiere tomar la parte entera "General-Dirección-literal" a cabo.

Aquí está la derivación:

Let-dig = ALPHA / DIGIT =~ [0-9A-Za-z] Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig =~ [0-9A-Za-z-]*[0-9A-Za-z] (regex is updated to make sure sub-domains are max. 63 charactes long - RFC 1034 section 3.5) sub-domain = Let-dig [Ldh-str] =~ [0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])? Domain = sub-domain *("." sub-domain) =~ [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])?)* Snum = 1*3DIGIT =~ [0-9]{1,3} (suggested replacement for "Snum") ip4-octet = DIGIT / %x31-39 DIGIT / "1" 2DIGIT / "2" %x30-34 DIGIT / "25" %x30-35 =~ 25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9] IPv4-address-literal = Snum 3("." Snum) =~ [0-9]{1,3}(/.[0-9]{1,3}){3} (suggested replacement for "IPv4-address-literal") ip4-address = ip4-octet 3("." ip4-octet) =~ (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} (suggested replacement for "IPv6-hex") ip6-h16 = "0" / ( (%x49-57 / %x65-70 /%x97-102) 0*3(%x48-57 / %x65-70 /%x97-102) ) =~ 0|[1-9A-Fa-f][0-9A-Fa-f]{0,3} (not from RFC) ls32 = ip6-h16 ":" ip6-h16 / ip4-address =~ (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} (suggested replacement of "IPv6-addr") ip6-address = 6(ip6-h16 ":") ls32 / "::" 5(ip6-h16 ":") ls32 / [ ip6-h16 ] "::" 4(ip6-h16 ":") ls32 / [ *1(ip6-h16 ":") ip6-h16 ] "::" 3(ip6-h16 ":") ls32 / [ *2(ip6-h16 ":") ip6-h16 ] "::" 2(ip6-h16 ":") ls32 / [ *3(ip6-h16 ":") ip6-h16 ] "::" ip6-h16 ":" ls32 / [ *4(ip6-h16 ":") ip6-h16 ] "::" ls32 / [ *5(ip6-h16 ":") ip6-h16 ] "::" ip6-h16 / [ *6(ip6-h16 ":") ip6-h16 ] "::" =~ (((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-address-literal = "IPv6:" ip6-address =~ 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}))?::) Standardized-tag = Ldh-str =~ [0-9A-Za-z-]*[0-9A-Za-z] dcontent = %d33-90 / %d94-126 =~ [!-Z^-~] General-address-literal = Standardized-tag ":" 1*dcontent =~ [0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+ address-literal = "[" ( IPv4-address-literal / IPv6-address-literal / General-address-literal ) "]" =~ /[((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^-~]+)] Mailbox = Local-part "@" ( Domain / address-literal ) =~ ([-!#-''*+/-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^-~]+)])

la validación de entrada de usuario

Un caso de uso común es la validación de entrada de usuario, por ejemplo en un formulario HTML. En ese caso, por lo general es razonable excluye dirección literales y requiere al menos dos etiquetas en el nombre de host. Tomando el mejorado RFC 5321 de expresiones regulares de la sección anterior como base, la expresión resultante sería:

([-!#-''*+/-9=?AZ^-~]+(/.[-!#-''*+/-9=?AZ^-~]+)*|"([]!#-[^-~ /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 la restricción de la parte local mayor, como la que impide cadenas entre comillas, ya que no sabemos qué tipo de nombres de buzón algunos hosts allow (como "a..b"@example.neto incluso "ab"@example.net).

Asimismo, no recomiendo explícitamente la validación con una lista de dominios de nivel superior literales o incluso la imposición de restricciones de longitud-(recuerda cómo ".museum" invalidado [az]{2,4}), pero si es necesario:

([-!#-''*+/-9=?AZ^-~]+(/.[-!#-''*+/-9=?AZ^-~]+)*|"([]!#-[^-~ /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 hasta a la fecha, si usted decide ir por el camino de validación de dominio de nivel superior explícita.

otras consideraciones

Cuando sólo aceptar los nombres de host en la parte del dominio (después del signo @), por encima de las expresiones regulares sólo aceptan etiquetas con un máximo de 63 caracteres, como debe ser. Sin embargo, ellos no hacen cumplir el hecho de que todo el nombre de host debe ser como máximo de 253 caracteres (incluyendo los puntos). A pesar de esta limitación es estrictamente hablando todavía regular, no es factible hacer una expresión regular que incorpora esta regla.

Otra consideración, especialmente cuando se utilizan las expresiones regulares para la validación de entrada, es la retroalimentación para el usuario. Si un usuario introduce una dirección incorrecta, que sería bueno para dar un poco más de retroalimentación que un simple "dirección sintácticamente incorrecto". Con expresiones regulares "vainilla" esto no es posible.

Estas dos consideraciones podrían abordarse mediante análisis de la dirección. La restricción de longitud extra en los nombres de host podría en algunos casos también se abordará mediante el uso de una expresión regular adicional que comprueba, y coincide con la dirección en contra de las dos expresiones.

Ninguna de las expresiones regulares en esta respuesta están optimizados para el rendimiento. Si el rendimiento es un problema, se debe ver si (y cómo) la expresión regular de su elección puede ser optimizado.


Una expresión regular simple, que al menos no rechazar cualquier dirección de correo electrónico válida sería el registro de algo, seguido por un signo @ y luego algo seguido de un punto y al menos 2 tantos. No va a rechazar cualquier cosa, pero después de revisar la especificación no puedo encontrar cualquier correo electrónico que sea válida y rechazado.

email = ~ /.+@[^@]+/.[^@]{2,}$/


Esta expresión regular es de Perl de correo electrónico :: Válido biblioteca. Yo creo que es el más preciso, que se empareja con todos 822. Y, que se basa en la expresión regular en el libro de O''Reilly:

Expresión regular construido usando el ejemplo de Jeffrey Friedl en dominio de expresiones regulares ( http://www.ora.com/catalog/regexp/ ).

$RFC822PAT = <<''EOF''; [/040/t]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80-/xff]|/([^///x80-/ xff/n/015()]*(?://[^/x80-/xff][^///x80-/xff/n/015()]*)*/))[^///x80-/xf f/n/015()]*)*/)[/040/t]*)*(?:(?:[^(/040)<>@,;:".///[/]/000-/037/x80-/x ff]+(?![^(/040)<>@,;:".///[/]/000-/037/x80-/xff])|"[^///x80-/xff/n/015 "]*(?://[^/x80-/xff][^///x80-/xff/n/015"]*)*")[/040/t]*(?:/([^///x80-/ xff/n/015()]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^/x80 -/xff][^///x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015()]*)*/)[/040/t]* )*(?:/.[/040/t]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80-/xff]|/([^/ //x80-/xff/n/015()]*(?://[^/x80-/xff][^///x80-/xff/n/015()]*)*/))[^/// x80-/xff/n/015()]*)*/)[/040/t]*)*(?:[^(/040)<>@,;:".///[/]/000-/037/x8 0-/xff]+(?![^(/040)<>@,;:".///[/]/000-/037/x80-/xff])|"[^///x80-/xff/n /015"]*(?://[^/x80-/xff][^///x80-/xff/n/015"]*)*")[/040/t]*(?:/([^///x 80-/xff/n/015()]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^ /x80-/xff][^///x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015()]*)*/)[/040 /t]*)*)*@[/040/t]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80-/xff]|/([ ^///x80-/xff/n/015()]*(?://[^/x80-/xff][^///x80-/xff/n/015()]*)*/))[^/ //x80-/xff/n/015()]*)*/)[/040/t]*)*(?:[^(/040)<>@,;:".///[/]/000-/037/ x80-/xff]+(?![^(/040)<>@,;:".///[/]/000-/037/x80-/xff])|/[(?:[^///x80- /xff/n/015/[/]]|//[^/x80-/xff])*/])[/040/t]*(?:/([^///x80-/xff/n/015() ]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^/x80-/xff][^/// x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015()]*)*/)[/040/t]*)*(?:/.[/04 0/t]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/ n/015()]*(?://[^/x80-/xff][^///x80-/xff/n/015()]*)*/))[^///x80-/xff/n/ 015()]*)*/)[/040/t]*)*(?:[^(/040)<>@,;:".///[/]/000-/037/x80-/xff]+(?! [^(/040)<>@,;:".///[/]/000-/037/x80-/xff])|/[(?:[^///x80-/xff/n/015/[/ ]]|//[^/x80-/xff])*/])[/040/t]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/ x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^/x80-/xff][^///x80-/xff/n/01 5()]*)*/))[^///x80-/xff/n/015()]*)*/)[/040/t]*)*)*|(?:[^(/040)<>@,;:". ///[/]/000-/037/x80-/xff]+(?![^(/040)<>@,;:".///[/]/000-/037/x80-/xff] )|"[^///x80-/xff/n/015"]*(?://[^/x80-/xff][^///x80-/xff/n/015"]*)*")[^ ()<>@,;:".///[/]/x80-/xff/000-/010/012-/037]*(?:(?:/([^///x80-/xff/n/0 15()]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^/x80-/xff][ ^///x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015()]*)*/)|"[^///x80-/xff/ n/015"]*(?://[^/x80-/xff][^///x80-/xff/n/015"]*)*")[^()<>@,;:".///[/]/ x80-/xff/000-/010/012-/037]*)*<[/040/t]*(?:/([^///x80-/xff/n/015()]*(? :(?://[^/x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^/x80-/xff][^///x80- /xff/n/015()]*)*/))[^///x80-/xff/n/015()]*)*/)[/040/t]*)*(?:@[/040/t]* (?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015 ()]*(?://[^/x80-/xff][^///x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015() ]*)*/)[/040/t]*)*(?:[^(/040)<>@,;:".///[/]/000-/037/x80-/xff]+(?![^(/0 40)<>@,;:".///[/]/000-/037/x80-/xff])|/[(?:[^///x80-/xff/n/015/[/]]|// [^/x80-/xff])*/])[/040/t]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80-/ xff]|/([^///x80-/xff/n/015()]*(?://[^/x80-/xff][^///x80-/xff/n/015()]* )*/))[^///x80-/xff/n/015()]*)*/)[/040/t]*)*(?:/.[/040/t]*(?:/([^///x80 -/xff/n/015()]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^/x 80-/xff][^///x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015()]*)*/)[/040/t ]*)*(?:[^(/040)<>@,;:".///[/]/000-/037/x80-/xff]+(?![^(/040)<>@,;:".// /[/]/000-/037/x80-/xff])|/[(?:[^///x80-/xff/n/015/[/]]|//[^/x80-/xff]) */])[/040/t]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80-/xff]|/([^///x 80-/xff/n/015()]*(?://[^/x80-/xff][^///x80-/xff/n/015()]*)*/))[^///x80 -/xff/n/015()]*)*/)[/040/t]*)*)*(?:,[/040/t]*(?:/([^///x80-/xff/n/015( )]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^/x80-/xff][^// /x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015()]*)*/)[/040/t]*)*@[/040/t ]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/0 15()]*(?://[^/x80-/xff][^///x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015 ()]*)*/)[/040/t]*)*(?:[^(/040)<>@,;:".///[/]/000-/037/x80-/xff]+(?![^( /040)<>@,;:".///[/]/000-/037/x80-/xff])|/[(?:[^///x80-/xff/n/015/[/]]| //[^/x80-/xff])*/])[/040/t]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80 -/xff]|/([^///x80-/xff/n/015()]*(?://[^/x80-/xff][^///x80-/xff/n/015() ]*)*/))[^///x80-/xff/n/015()]*)*/)[/040/t]*)*(?:/.[/040/t]*(?:/([^///x 80-/xff/n/015()]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^ /x80-/xff][^///x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015()]*)*/)[/040 /t]*)*(?:[^(/040)<>@,;:".///[/]/000-/037/x80-/xff]+(?![^(/040)<>@,;:". ///[/]/000-/037/x80-/xff])|/[(?:[^///x80-/xff/n/015/[/]]|//[^/x80-/xff ])*/])[/040/t]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80-/xff]|/([^// /x80-/xff/n/015()]*(?://[^/x80-/xff][^///x80-/xff/n/015()]*)*/))[^///x 80-/xff/n/015()]*)*/)[/040/t]*)*)*)*:[/040/t]*(?:/([^///x80-/xff/n/015 ()]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^/x80-/xff][^/ //x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015()]*)*/)[/040/t]*)*)?(?:[^ (/040)<>@,;:".///[/]/000-/037/x80-/xff]+(?![^(/040)<>@,;:".///[/]/000- /037/x80-/xff])|"[^///x80-/xff/n/015"]*(?://[^/x80-/xff][^///x80-/xff/ n/015"]*)*")[/040/t]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80-/xff]| /([^///x80-/xff/n/015()]*(?://[^/x80-/xff][^///x80-/xff/n/015()]*)*/)) [^///x80-/xff/n/015()]*)*/)[/040/t]*)*(?:/.[/040/t]*(?:/([^///x80-/xff /n/015()]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^/x80-/x ff][^///x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015()]*)*/)[/040/t]*)*( ?:[^(/040)<>@,;:".///[/]/000-/037/x80-/xff]+(?![^(/040)<>@,;:".///[/]/ 000-/037/x80-/xff])|"[^///x80-/xff/n/015"]*(?://[^/x80-/xff][^///x80-/ xff/n/015"]*)*")[/040/t]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80-/x ff]|/([^///x80-/xff/n/015()]*(?://[^/x80-/xff][^///x80-/xff/n/015()]*) */))[^///x80-/xff/n/015()]*)*/)[/040/t]*)*)*@[/040/t]*(?:/([^///x80-/x ff/n/015()]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^/x80- /xff][^///x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015()]*)*/)[/040/t]*) *(?:[^(/040)<>@,;:".///[/]/000-/037/x80-/xff]+(?![^(/040)<>@,;:".///[/ ]/000-/037/x80-/xff])|/[(?:[^///x80-/xff/n/015/[/]]|//[^/x80-/xff])*/] )[/040/t]*(?:/([^///x80-/xff/n/015()]*(?:(?://[^/x80-/xff]|/([^///x80- /xff/n/015()]*(?://[^/x80-/xff][^///x80-/xff/n/015()]*)*/))[^///x80-/x ff/n/015()]*)*/)[/040/t]*)*(?:/.[/040/t]*(?:/([^///x80-/xff/n/015()]*( ?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015()]*(?://[^/x80-/xff][^///x80 -/xff/n/015()]*)*/))[^///x80-/xff/n/015()]*)*/)[/040/t]*)*(?:[^(/040)< >@,;:".///[/]/000-/037/x80-/xff]+(?![^(/040)<>@,;:".///[/]/000-/037/x8 0-/xff])|/[(?:[^///x80-/xff/n/015/[/]]|//[^/x80-/xff])*/])[/040/t]*(?: /([^///x80-/xff/n/015()]*(?:(?://[^/x80-/xff]|/([^///x80-/xff/n/015()] *(?://[^/x80-/xff][^///x80-/xff/n/015()]*)*/))[^///x80-/xff/n/015()]*) */)[/040/t]*)*)*>) EOF


La especificación HTML5 sugiere una expresión regular simple para validar direcciones de correo electrónico:

/^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:/.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/

Este intencionalmente no cumple con RFC 5322 .

Nota: Este requisito es una violación intencional del RFC 5322 , que define una sintaxis para las direcciones de correo electrónico que es a la vez demasiado estricto (antes de que el @personaje), demasiado vaga (después de que el @personaje), y demasiado laxa (que permite comentarios, espacios en blanco, y cadenas entre comillas en las costumbres desconocidas para la mayoría de usuarios) para ser de uso práctico aquí.

La longitud total también podría limitarse a 254 caracteres, por RFC 3696 errata 1690 .


RFC 5322 estándar:

Permite punto-átomo de parte-local, cita de cadena local de partes, obsoleto (mixta punto-átomo y cita de cadena) parte-local, el nombre de dominio de dominio, (asignada a IPv4 IPv4, IPv6 y la dirección IPv6) de dominio de dominio literal, y (anidada) CFWS.

''/^(?!(?>(?1)"?(?>///[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>///[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>/x0D/x0A)?[/t ])+|(?>[/t ]*/x0D/x0A)?[/t ]+)?)(/((?>(?2)(?>[/x01-/x08/x0B/x0C/x0E-/'*-/[/]-/x7F]|///[/x00-/x7F]|(?3)))*(?2)/)))+(?2))|(?2))?)([!#-/'*+//-9=?^-~-]+|"(?>(?2)(?>[/x01-/x08/x0B/x0C/x0E-!#-/[/]-/x7F]|///[/x00-/x7F]))*(?2)")(?>(?1)/.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>(?1)/.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|/[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f0-9][:/]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>/.(?9)){3}))/])(?1)$/isD''

RFC 5321 estándar:

Permite punto-átomo de parte-local, cita de cadena local de partes, de dominio nombre de dominio y el dominio literal (dirección IPv6 asignada de IPv4 IPv4, IPv6, y) de dominio.

''/^(?!(?>"?(?>///[ -~]|[^"])"?){255,})(?!"?(?>///[ -~]|[^"]){65,}"?@)(?>([!#-/'*+//-9=?^-~-]+)(?>/.(?1))*|"(?>[ !#-/[/]-~]|///[ -~])*")@(?!.*[^.]{64,})(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>/.(?2)){0,126}|/[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?3)){7}|(?!(?:.*[a-f0-9][:/]]){8,})((?3)(?>:(?3)){0,6})?::(?4)?))|(?>(?>IPv6:(?>(?3)(?>:(?3)){5}:|(?!(?:.*[a-f0-9]:){6,})(?5)?::(?>((?3)(?>:(?3)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>/.(?6)){3}))/])$/iD''

BASIC:

Permite dot-átomo de parte-local y nombre de dominio del dominio (que requiera al menos dos etiquetas de nombres de dominio con el TLD limitado a 2-6 caracteres alfabéticos).

"/^(?!.{255,})(?!.{65,}@)([!#-''*+//-9=?^-~-]+)(?>/.(?1))*@(?!.*[^.]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?/.){1,126}[a-z]{2,6}$/iD"



Al decidir qué caracteres están permitidos, por favor recuerde que su apostrophed y amigos con guiones. No tengo ningún 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 he estado bloqueado de la interacción con un sitio web por el hecho de que mi dirección de correo electrónico es "válido".


Hay un montón de ejemplos de este cabo en la red (y creo que incluso uno que valida totalmente el RFC - pero es decenas / cientos de líneas largas si mal no recuerdo). La gente tiende a dejarse llevar validar este tipo de cosas. ¿Por qué no acaba de comprobar que tiene una @ y al menos una. y cumple con alguna longitud mínima simple. Es trivial para entrar en un correo electrónico falso y todavía adaptarse a cualquier expresión regular válida de todos modos. Me imagino que los falsos positivos son mejores que los falsos negativos.


Nunca moleste crear con mi propia expresión regular, porque lo más probable es que alguien ya ha llegado con una versión mejor. Siempre uso regexlib encontrar uno de mi agrado.


Por extraño que "no se puede" permitir que 4 caracteres TLD. Usted está prohibiendo la gente de .info y .name , y la parada de limitación de la longitud .travel y .museum , pero eso sí, son menos comunes que los TLDs 2 caracteres y 3 caracteres TLD.

Usted debe permitir alfabetos en mayúsculas también. sistemas de correo electrónico se normalizarán la parte pieza y dominio local.

Para su expresión regular de la parte de dominio, nombre de dominio no puede comienza con ''-'' y no puede termina con ''-''. Dash sólo puede se queda en el medio.

Si ha utilizado la biblioteca PEAR, echa un vistazo a su función de correo (olvidé el nombre exacto / biblioteca). Puede validar la dirección de correo electrónico llamando a una función, y se valida la dirección de correo electrónico de acuerdo con la definición contenida en RFC822.


Las direcciones de correo electrónico que deseo validar van a ser 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 expresiones regulares muy complejas, intento crear una instancia de MailAddress desde la dirección. El constructor de MailAddress arrojará una excepción si la dirección no está formada correctamente. De esta manera, sé que al menos puedo recibir el correo electrónico por la puerta. Por supuesto, esta es la validación del lado del servidor, pero como mínimo lo necesitas de todos modos.

protected void emailValidator_ServerValidate(object source, ServerValidateEventArgs args) { try { var a = new MailAddress(txtEmail.Text); } catch (Exception ex) { args.IsValid = false; emailValidator.ErrorMessage = "email: " + ex.Message; } }


No sé cuál es el mejor, pero este es al menos correcto, siempre que las direcciones tengan sus comentarios eliminados y reemplazados con espacios en blanco.

Seriamente. Debe usar una biblioteca ya escrita para validar correos electrónicos. La mejor manera es enviar un correo electrónico de verificación a esa dirección.


Se podría utilizar la empleada por el plugin jQuery Validación:

/^((([a-z]|/d|[!#/$%&''/*/+/-//=/?/^_`{/|}~]|[/u00A0-/uD7FF/uF900-/uFDCF/uFDF0-/uFFEF])+(/.([a-z]|/d|[!#/$%&''/*/+/-//=/?/^_`{/|}~]|[/u00A0-/uD7FF/uF900-/uFDCF/uFDF0-/uFFEF])+)*)|((/x22)((((/x20|/x09)*(/x0d/x0a))?(/x20|/x09)+)?(([/x01-/x08/x0b/x0c/x0e-/x1f/x7f]|/x21|[/x23-/x5b]|[/x5d-/x7e]|[/u00A0-/uD7FF/uF900-/uFDCF/uFDF0-/uFFEF])|(//([/x01-/x09/x0b/x0c/x0d-/x7f]|[/u00A0-/uD7FF/uF900-/uFDCF/uFDF0-/uFFEF]))))*(((/x20|/x09)*(/x0d/x0a))?(/x20|/x09)+)?(/x22)))@((([a-z]|/d|[/u00A0-/uD7FF/uF900-/uFDCF/uFDF0-/uFFEF])|(([a-z]|/d|[/u00A0-/uD7FF/uF900-/uFDCF/uFDF0-/uFFEF])([a-z]|/d|-|/.|_|~|[/u00A0-/uD7FF/uF900-/uFDCF/uFDF0-/uFFEF])*([a-z]|/d|[/u00A0-/uD7FF/uF900-/uFDCF/uFDF0-/uFFEF])))/.)+(([a-z]|[/u00A0-/uD7FF/uF900-/uFDCF/uFDF0-/uFFEF])|(([a-z]|[/u00A0-/uD7FF/uF900-/uFDCF/uFDF0-/uFFEF])([a-z]|/d|-|/.|_|~|[/u00A0-/uD7FF/uF900-/uFDCF/uFDF0-/uFFEF])*([a-z]|[/u00A0-/uD7FF/uF900-/uFDCF/uFDF0-/uFFEF])))/.?$/i


Para una demostración viva, el siguiente monstruo es bastante bueno, pero todavía no reconoce correctamente todas las direcciones de correo electrónico sintácticamente válidos: reconoce los comentarios anidados hasta cuatro niveles de profundidad.

Este es un trabajo para un programa de análisis, pero incluso si una dirección es sintácticamente válida, todavía no se pueden liberar. A veces hay que recurrir al método del hillbilly "Hey, ustedes, ver ee-nosotros!"

// derivative of work with the following copyright and license: // Copyright (c) 2004 Casey West. All rights reserved. // This module is free software; you can redistribute it and/or // modify it under the same terms as Perl itself. // see http://search.cpan.org/~cwest/Email-Address-1.80/ private static string gibberish = @" (?-xism:(?:(?-xism:(?-xism:(?-xism:(?-xism:(?-xism:(?-xism:/ s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^ /x0A/x0D]))|(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+)) |(?-xism://(?-xism:[^/x0A/x0D]))|)+)*/s*/)/s*))+)*/s*/)/s*)+ |/s+)*[^/x00-/x1F/x7F()<>/[/]:;@/,.<DQ>/s]+(?-xism:(?-xism:/ s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^ /x0A/x0D]))|(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+)) |(?-xism://(?-xism:[^/x0A/x0D]))|)+)*/s*/)/s*))+)*/s*/)/s*)+ |/s+)*)|(?-xism:(?-xism:(?-xism:/s*/((?:/s*(?-xism:(?-xism:( ?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|(?-xism:/s*/((? :/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x 0D]))|)+)*/s*/)/s*))+)*/s*/)/s*)+|/s+)*<DQ>(?-xism:(?-xism:[ ^//<DQ>])|(?-xism://(?-xism:[^/x0A/x0D])))+<DQ>(?-xism:(?-xi sm:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xis m:[^/x0A/x0D]))|(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()// ]+))|(?-xism://(?-xism:[^/x0A/x0D]))|)+)*/s*/)/s*))+)*/s*/)/ s*)+|/s+)*))+)?(?-xism:(?-xism:(?-xism:/s*/((?:/s*(?-xism:(? -xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|(?-xism: /s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[ ^/x0A/x0D]))|)+)*/s*/)/s*))+)*/s*/)/s*)+|/s+)*<(?-xism:(?-xi sm:(?-xism:(?-xism:(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^( )//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|(?-xism:/s*/((?:/s*( ?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D])) |)+)*/s*/)/s*))+)*/s*/)/s*)+|/s+)*(?-xism:[^/x00-/x1F/x7F()< >/[/]:;@/,.<DQ>/s]+(?:/.[^/x00-/x1F/x7F()<>/[/]:;@/,.<DQ>/s] +)*)(?-xism:(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+)) |(?-xism://(?-xism:[^/x0A/x0D]))|(?-xism:/s*/((?:/s*(?-xism: (?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|)+)*/s */)/s*))+)*/s*/)/s*)+|/s+)*)|(?-xism:(?-xism:(?-xism:/s*/((? :/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x 0D]))|(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xi sm://(?-xism:[^/x0A/x0D]))|)+)*/s*/)/s*))+)*/s*/)/s*)+|/s+)* <DQ>(?-xism:(?-xism:[^//<DQ>])|(?-xism://(?-xism:[^/x0A/x0D] )))+<DQ>(?-xism:(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()// ]+))|(?-xism://(?-xism:[^/x0A/x0D]))|(?-xism:/s*/((?:/s*(?-x ism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|)+ )*/s*/)/s*))+)*/s*/)/s*)+|/s+)*))/@(?-xism:(?-xism:(?-xism:( ?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(? -xism:[^/x0A/x0D]))|(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^ ()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|)+)*/s*/)/s*))+)*/s */)/s*)+|/s+)*(?-xism:[^/x00-/x1F/x7F()<>/[/]:;@/,.<DQ>/s]+( ?:/.[^/x00-/x1F/x7F()<>/[/]:;@/,.<DQ>/s]+)*)(?-xism:(?-xism: /s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[ ^/x0A/x0D]))|(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+) )|(?-xism://(?-xism:[^/x0A/x0D]))|)+)*/s*/)/s*))+)*/s*/)/s*) +|/s+)*)|(?-xism:(?-xism:(?-xism:/s*/((?:/s*(?-xism:(?-xism: (?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|(?-xism:/s*/(( ?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/ x0D]))|)+)*/s*/)/s*))+)*/s*/)/s*)+|/s+)*/[(?:/s*(?-xism:(?-x ism:[^/[/]//])|(?-xism://(?-xism:[^/x0A/x0D])))+)*/s*/](?-xi sm:(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism: //(?-xism:[^/x0A/x0D]))|(?-xism:/s*/((?:/s*(?-xism:(?-xism:( ?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|)+)*/s*/)/s*))+ )*/s*/)/s*)+|/s+)*)))>(?-xism:(?-xism:/s*/((?:/s*(?-xism:(?- xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|(?-xism:/ s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^ /x0A/x0D]))|)+)*/s*/)/s*))+)*/s*/)/s*)+|/s+)*))|(?-xism:(?-x ism:(?-xism:(?-xism:(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^ ()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|(?-xism:/s*/((?:/s* (?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]) )|)+)*/s*/)/s*))+)*/s*/)/s*)+|/s+)*(?-xism:[^/x00-/x1F/x7F() <>/[/]:;@/,.<DQ>/s]+(?:/.[^/x00-/x1F/x7F()<>/[/]:;@/,.<DQ>/s ]+)*)(?-xism:(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+) )|(?-xism://(?-xism:[^/x0A/x0D]))|(?-xism:/s*/((?:/s*(?-xism :(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|)+)*/ s*/)/s*))+)*/s*/)/s*)+|/s+)*)|(?-xism:(?-xism:(?-xism:/s*/(( ?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/ x0D]))|(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-x ism://(?-xism:[^/x0A/x0D]))|)+)*/s*/)/s*))+)*/s*/)/s*)+|/s+) *<DQ>(?-xism:(?-xism:[^//<DQ>])|(?-xism://(?-xism:[^/x0A/x0D ])))+<DQ>(?-xism:(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()/ /]+))|(?-xism://(?-xism:[^/x0A/x0D]))|(?-xism:/s*/((?:/s*(?- xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|) +)*/s*/)/s*))+)*/s*/)/s*)+|/s+)*))/@(?-xism:(?-xism:(?-xism: (?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://( ?-xism:[^/x0A/x0D]))|(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[ ^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|)+)*/s*/)/s*))+)*/ s*/)/s*)+|/s+)*(?-xism:[^/x00-/x1F/x7F()<>/[/]:;@/,.<DQ>/s]+ (?:/.[^/x00-/x1F/x7F()<>/[/]:;@/,.<DQ>/s]+)*)(?-xism:(?-xism :/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism: [^/x0A/x0D]))|(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+ ))|(?-xism://(?-xism:[^/x0A/x0D]))|)+)*/s*/)/s*))+)*/s*/)/s* )+|/s+)*)|(?-xism:(?-xism:(?-xism:/s*/((?:/s*(?-xism:(?-xism :(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|(?-xism:/s*/( (?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A /x0D]))|)+)*/s*/)/s*))+)*/s*/)/s*)+|/s+)*/[(?:/s*(?-xism:(?- xism:[^/[/]//])|(?-xism://(?-xism:[^/x0A/x0D])))+)*/s*/](?-x ism:(?-xism:/s*/((?:/s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism ://(?-xism:[^/x0A/x0D]))|(?-xism:/s*/((?:/s*(?-xism:(?-xism: (?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|)+)*/s*/)/s*)) +)*/s*/)/s*)+|/s+)*))))(?-xism:/s*/((?:/s*(?-xism:(?-xism:(? >[^()//]+))|(?-xism://(?-xism:[^/x0A/x0D]))|(?-xism:/s*/((?: /s*(?-xism:(?-xism:(?>[^()//]+))|(?-xism://(?-xism:[^/x0A/x0 D]))|)+)*/s*/)/s*))+)*/s*/)/s*)*)" .Replace("<DQ>", "/"") .Replace("/t", "") .Replace(" ", "") .Replace("/r", "") .Replace("/n", ""); private static Regex mailbox = new Regex(gibberish, RegexOptions.ExplicitCapture);


Por no mencionar que no latino (chino, árabe, griego, hebreo, cirílico, etc.) son los nombres de dominio que se le permita en el futuro cercano . Cada uno tiene que cambiar la expresión regular de correo electrónico utilizada, porque esos personajes son seguramente no estar cubiertos por [az]/ini /w. Todos ellos fallarán.

Después de todo, la mejor manera de validar la dirección de correo electrónico está siendo realmente 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 de usuario (registro / login / etc), entonces se puede combinar perfectamente con el sistema de activación de usuario. Es decir, enviar un correo electrónico con un enlace con una clave de activación exclusivo a la dirección de correo electrónico especificada y sólo permite inicio de sesión cuando el usuario ha activado la cuenta recién creada mediante el enlace del correo electrónico.

Si el propósito de la expresión regular es sólo para informar rápidamente al usuario en la interfaz de usuario que la dirección de correo electrónico especificada no se ve como en el formato correcto, es mejor fotografía para comprobar si coincide, básicamente, la siguiente expresión regular:

^([^.@]+)(/.[^.@]+)*@([^.@]+/.)+([^.@]+)$

Simple como eso.¿Por qué en la tierra que usted se preocupa por los caracteres utilizados en el nombre y el dominio? Es responsabilidad del cliente para introducir una dirección de correo electrónico válida, no el servidor de. Incluso cuando el cliente entra en una sintácticamente dirección de correo electrónico válida como [email protected], esto no garantiza que se trata de una dirección de correo electrónico de fiar. Nadie expresiones regulares puede cubrir eso.


Para la evaluación más completa de la mejor expresión regular para validar una dirección de correo electrónico consulte este enlace; " Comparando Dirección de correo electrónico Validación de expresiones regulares "

Aquí es la expresión superior actual a título de referencia:

/^([/w/!/#$/%/&/'/*/+/-///=/?/^/`{/|/}/~]+/.)*[/w/!/#$/%/&/'/*/+/-///=/?/^/`{/|/}/~]+@((((([a-z0-9]{1}[a-z0-9/-]{0,62}[a-z0-9]{1})|[a-z])/.)+[a-z]{2,6})|(/d{1,3}/.){3}/d{1,3}(/:/d{1,5})?)$/i


No debe usar 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 }

La clase MailAddress usa un analizador BNF para validar la dirección de acuerdo con RFC822.

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

(?:(?:/r/n)?[ /t])*(?:(?:(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t] )+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?: /r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:( ?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*))*@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/0 31]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/ ](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+ (?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?: (?:/r/n)?[ /t])*))*|(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z |(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n) ?[ /t])*)*/<(?:(?:/r/n)?[ /t])*(?:@(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/ r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n) ?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t] )*))*(?:,@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])* )(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t] )+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*) *:(?:(?:/r/n)?[ /t])*)?(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+ |/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r /n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?: /r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t ]))*"(?:(?:/r/n)?[ /t])*))*@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031 ]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/]( ?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(? :(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(? :/r/n)?[ /t])*))*/>(?:(?:/r/n)?[ /t])*)|(?:[^()<>@,;://"./[/] /000-/031]+(?:(? :(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)? [ /t]))*"(?:(?:/r/n)?[ /t])*)*:(?:(?:/r/n)?[ /t])*(?:(?:(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]| //.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<> @,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|" (?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*))*@(?:(?:/r/n)?[ /t] )*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;:// "./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(? :[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[ /]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*|(?:[^()<>@,;://"./[/] /000- /031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|( ?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*)*/<(?:(?:/r/n)?[ /t])*(?:@(?:[^()<>@,; ://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([ ^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://" ./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/ ]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*(?:,@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./ [/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/ r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//] |//.)*/](?:(?:/r/n)?[ /t])*))*)*:(?:(?:/r/n)?[ /t])*)?(?:[^()<>@,;://"./[/] /0 00-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|// .|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@, ;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(? :[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*))*@(?:(?:/r/n)?[ /t])* (?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://". /[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[ ^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/] ]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*/>(?:(?:/r/n)?[ /t])*)(?:,/s*( ?:(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;:// "./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*)(?:/.(?:( ?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[ /["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t ])*))*@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t ])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(? :/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+| /Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*|(?: [^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/ ]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*)*/<(?:(?:/r/n) ?[ /t])*(?:@(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/[" ()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n) ?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<> @,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*(?:,@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@, ;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t] )*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;:// "./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*)*:(?:(?:/r/n)?[ /t])*)? (?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://". /[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*)(?:/.(?:(?: /r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/[ "()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t]) *))*@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t]) +|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/ .(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z |(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*/>(?:( ?:/r/n)?[ /t])*))*)?;/s*)


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

  • No detectará errores tipográficos comunes.
  • No impide que las personas ingresen direcciones de correo electrónico no vá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 opción que enviar un correo electrónico de confirmación y hacer que el usuario responda a eso. En muchos casos, tendrá que enviar un correo de confirmación de todos modos por razones de seguridad o por razones éticas (por lo tanto, no puede, por ejemplo, firmar a alguien en un servicio en contra de su voluntad).


Aquí está el PHP que uso. He elegido esta solución en el espíritu de "falsos positivos son mejores que los falsos negativos" de los declarados por otro comentarista aquí y en lo que respecta a mantener su tiempo de respuesta y carga del servidor abajo ... no hay realmente ninguna necesidad de perder los recursos del servidor con una expresión regular cuándo va a eliminar a un error del usuario más sencilla. Siempre se puede seguir esto mediante el envío de un correo electrónico de prueba si lo desea.

function validateEmail($email) { return (bool) stripos($email,''@''); }


public bool ValidateEmail(string sEmail) { if (sEmail == null) { return false; } int nFirstAT = sEmail.IndexOf(''@''); int nLastAT = sEmail.LastIndexOf(''@''); if ((nFirstAT > 0) && (nLastAT == nFirstAT) && (nFirstAT < (sEmail.Length - 1))) { return (Regex.IsMatch(sEmail, @"^[a-z|0-9|A-Z]*([_][a-z|0-9|A-Z]+)*([.][a-z|0-9|A-Z]+)*([.][a-z|0-9|A-Z]+)*(([_][a-z|0-9|A-Z]+)*)?@[a-z][a-z|0-9|A-Z]*/.([a-z][a-z|0-9|A-Z]*(/.[a-z][a-z|0-9|A-Z]*)?)$")); } else { return false; } }


De acuerdo con la norma oficial RFC 2822 de correo electrónico válida expresión regular es

(?:[a-z0-9!#$%&''*+/=?^_`{|}~-]+(?:/.[a-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])+)/])

si desea utilizarlo en Java es realmente muy fácil

import java.util.regex.*; class regexSample { public static void main(String args[]) { //Input the string for validation String email = "[email protected]"; //Set the email pattern string Pattern p = Pattern.compile(" (?:[a-z0-9!#$%&''*+/=?^_`{|}~-]+(?://.[a-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])+)//]"); //Match the given string with the pattern Matcher m = p.matcher(email); //check whether match is found boolean matchFound = m.matches(); if (matchFound) System.out.println("Valid Email Id."); else System.out.println("Invalid Email Id."); } }


Depende de a qué te refieras con mejor: si estás hablando de atrapar todas las direcciones de correo electrónico válidas, utiliza lo siguiente:

(?:(?:/r/n)?[ /t])*(?:(?:(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t] )+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?: /r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:( ?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*))*@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/0 31]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/ ](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+ (?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?: (?:/r/n)?[ /t])*))*|(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z |(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n) ?[ /t])*)*/<(?:(?:/r/n)?[ /t])*(?:@(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/ r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n) ?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t] )*))*(?:,@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])* )(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t] )+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*) *:(?:(?:/r/n)?[ /t])*)?(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+ |/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r /n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?: /r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t ]))*"(?:(?:/r/n)?[ /t])*))*@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031 ]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/]( ?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(? :(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(? :/r/n)?[ /t])*))*/>(?:(?:/r/n)?[ /t])*)|(?:[^()<>@,;://"./[/] /000-/031]+(?:(? :(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)? [ /t]))*"(?:(?:/r/n)?[ /t])*)*:(?:(?:/r/n)?[ /t])*(?:(?:(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]| //.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<> @,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|" (?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*))*@(?:(?:/r/n)?[ /t] )*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;:// "./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(? :[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[ /]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*|(?:[^()<>@,;://"./[/] /000- /031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|( ?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*)*/<(?:(?:/r/n)?[ /t])*(?:@(?:[^()<>@,; ://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([ ^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://" ./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/ ]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*(?:,@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./ [/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/ r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//] |//.)*/](?:(?:/r/n)?[ /t])*))*)*:(?:(?:/r/n)?[ /t])*)?(?:[^()<>@,;://"./[/] /0 00-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(?:[^/"/r//]|// .|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[^()<>@, ;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/]]))|"(? :[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*))*@(?:(?:/r/n)?[ /t])* (?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://". /[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t])*(?:[ ^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/] ]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*/>(?:(?:/r/n)?[ /t])*)(?:,/s*( ?:(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;:// "./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*)(?:/.(?:( ?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[ /["()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t ])*))*@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t ])+|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(? :/.(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+| /Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*|(?: [^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://"./[/ ]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*)*/<(?:(?:/r/n) ?[ /t])*(?:@(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/[" ()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n) ?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<> @,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*(?:,@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@, ;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/.(?:(?:/r/n)?[ /t] )*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;:// "./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*)*:(?:(?:/r/n)?[ /t])*)? (?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/["()<>@,;://". /[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t])*)(?:/.(?:(?: /r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z|(?=[/[ "()<>@,;://"./[/]]))|"(?:[^/"/r//]|//.|(?:(?:/r/n)?[ /t]))*"(?:(?:/r/n)?[ /t]) *))*@(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t]) +|/Z|(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*)(?:/ .(?:(?:/r/n)?[ /t])*(?:[^()<>@,;://"./[/] /000-/031]+(?:(?:(?:/r/n)?[ /t])+|/Z |(?=[/["()<>@,;://"./[/]]))|/[([^/[/]/r//]|//.)*/](?:(?:/r/n)?[ /t])*))*/>(?:( ?:/r/n)?[ /t])*))*)?;/s*)

( http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html ) Si está buscando algo más simple pero que captará la mayoría de las direcciones de correo electrónico válidas, pruebe algo como:

"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+/.[a-zA-Z0-9-.]+$"

EDITAR: Desde el enlace:

Esta expresión regular solo validará las direcciones a las que se les quitaron los comentarios y se los reemplazó por espacios en blanco (esto lo hace el módulo).


Es fácil en Perl 5.10 o más nuevo:

/(?(DEFINE) (?<address> (?&mailbox) | (?&group)) (?<mailbox> (?&name_addr) | (?&addr_spec)) (?<name_addr> (?&display_name)? (?&angle_addr)) (?<angle_addr> (?&CFWS)? < (?&addr_spec) > (?&CFWS)?) (?<group> (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ; (?&CFWS)?) (?<display_name> (?&phrase)) (?<mailbox_list> (?&mailbox) (?: , (?&mailbox))*) (?<addr_spec> (?&local_part) /@ (?&domain)) (?<local_part> (?&dot_atom) | (?&quoted_string)) (?<domain> (?&dot_atom) | (?&domain_literal)) (?<domain_literal> (?&CFWS)? /[ (?: (?&FWS)? (?&dcontent))* (?&FWS)? /] (?&CFWS)?) (?<dcontent> (?&dtext) | (?&quoted_pair)) (?<dtext> (?&NO_WS_CTL) | [/x21-/x5a/x5e-/x7e]) (?<atext> (?&ALPHA) | (?&DIGIT) | [!#/$%&''*+-/=?^_`{|}~]) (?<atom> (?&CFWS)? (?&atext)+ (?&CFWS)?) (?<dot_atom> (?&CFWS)? (?&dot_atom_text) (?&CFWS)?) (?<dot_atom_text> (?&atext)+ (?: /. (?&atext)+)*) (?<text> [/x01-/x09/x0b/x0c/x0e-/x7f]) (?<quoted_pair> // (?&text)) (?<qtext> (?&NO_WS_CTL) | [/x21/x23-/x5b/x5d-/x7e]) (?<qcontent> (?&qtext) | (?&quoted_pair)) (?<quoted_string> (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))* (?&FWS)? (?&DQUOTE) (?&CFWS)?) (?<word> (?&atom) | (?&quoted_string)) (?<phrase> (?&word)+) # Folding white space (?<FWS> (?: (?&WSP)* (?&CRLF))? (?&WSP)+) (?<ctext> (?&NO_WS_CTL) | [/x21-/x27/x2a-/x5b/x5d-/x7e]) (?<ccontent> (?&ctext) | (?&quoted_pair) | (?&comment)) (?<comment> /( (?: (?&FWS)? (?&ccontent))* (?&FWS)? /) ) (?<CFWS> (?: (?&FWS)? (?&comment))* (?: (?:(?&FWS)? (?&comment)) | (?&FWS))) # No whitespace control (?<NO_WS_CTL> [/x01-/x08/x0b/x0c/x0e-/x1f/x7f]) (?<ALPHA> [A-Za-z]) (?<DIGIT> [0-9]) (?<CRLF> /x0d /x0a) (?<DQUOTE> ") (?<WSP> [/x20/x09]) ) (?&address)/x


Según la especificación W3C HTML5 :

^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:/.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$

Contexto:

Una dirección válida de correo electrónico es una cadena que coincide con la producción ABNF [...].

Nota: Este requisito es una violación deliberada de RFC 5322 , que define una sintaxis para las direcciones de correo electrónico que es a la vez demasiado estricta (antes del carácter "@"), demasiado vaga (después del carácter "@") y demasiado laxa ( permitiendo que los comentarios, los espacios en blanco y las comillas de maneras poco familiares para la mayoría de los usuarios) sean de utilidad práctica aquí.

La siguiente expresión regular compatible con JavaScript y Perl es una implementación de la definición anterior.

/^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:/.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/


[ACTUALIZADO] He recopilado todo lo que sé sobre la validación de la dirección 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; ver mi ensayo en http://isemail.info/about .

is_email () sigue siendo, hasta donde sé, el único validador que le dirá definitivamente si una cadena determinada 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 libres que pude encontrar.

Trataré de 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 la crítica constructiva de mi propio validador .

La gente debería conocer la errata contra RFC 3696 en particular. Tres de los ejemplos canónicos son, de hecho, direcciones inválidas. Y la longitud máxima de una dirección es de 254 o 256 caracteres, no 320.


yo suelo

^/w+([-+.'']/w+)*@/w+([-.]/w+)*/./w+([-.]/w+)*$

¿Cuál es el que usa RegularExpressionValidator en ASP.NET?


Todo depende de qué tan preciso quieras ser. Para mis propósitos, donde estoy tratando de mantener fuera cosas como bob @ aol.com (espacios en correos electrónicos) o steve (sin dominio) o mary@aolcom (sin período antes de .com), uso

/^/S+@/S+/./S+$/

Claro, coincidirá con las cosas que no son direcciones de correo electrónico válidas, pero es una cuestión de jugar la regla 90/10.


La expresión regular totalmente compatible con RFC 822 es ineficaz 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.

Una expresión regular compatible con RFC 5322 se puede encontrar en la parte superior de la página en http://emailregex.com/ pero utiliza el patrón de dirección IP que está flotando 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, que es ilegal. El resto parece ser consistente con la gramática RFC 5322 y pasa varias pruebas usando grep -Po , incluidos casos de nombres de dominio, direcciones IP, datos incorrectos y nombres de cuentas con y sin comillas.

Corrigiendo el error 00 en el patrón IP, obtenemos una expresión regular bastante rápida y funcional. (Raspe la versión representada, no la marca, para el código real).

(?: [a-z0-9! # $% & ''* + / =? ^ _ `{|} ~ -] + (?: /. [a-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])? | / [(? :(? :( 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- / x08 / x0b / x0c / x0e- / x1f / x21- / x5a / x53- / x7f] | // [/ x01- / x09 / x0b / x0c / x0e- / x7f]) +) /])

Aquí hay un diagrama de la máquina de estados finitos para la expresión regular anterior, que es más claro que la propia expresión regular

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

También es importante comprender que validarlo según el RFC no le dice absolutamente nada sobre si esa dirección existe realmente en el dominio suministrado, o si la persona que ingresa la dirección es su verdadero propietario. Las personas firman otras listas de correo de esta manera todo el tiempo. La reparación requiere un tipo de validación más sofisticada que implique enviar a esa dirección un mensaje que incluya 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 tienes la dirección de la persona que ingresa. Esta es la razón por la que la mayoría de las listas de correo ahora usan ese mecanismo para confirmar las inscripciones. Después de todo, cualquiera puede dejar presionado [email protected] , y eso incluso lo analizará como legal, pero no es probable que sea la persona en el otro extremo.

Para PHP, no debe usar el patrón dado en Validar una dirección de correo electrónico con PHP, de la manera correcta desde la cual cito:

Existe cierto 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 otros patrones no RFC. Ni siquiera es lo suficientemente inteligente como para manejar incluso el RFC 822 , y mucho menos el RFC 5322. Este , sin embargo, sí lo es.

Si quieres ser 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 fin 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 agradable, como

La dirección de correo electrónico especificada ''myemail @ address, com'' no es válida. ¿Quisiste decir ''[email protected]''?

Consulte también Validar direcciones de correo electrónico , incluidos los comentarios. O comparar la dirección de correo electrónico Validar expresiones regulares .

Demostración de Debuggex



No hay uno que es realmente utilizable.
Discuto algunos problemas en mi respuesta a ¿Hay una librería PHP para la validación de direcciones de correo electrónico? , Se discute también en el reconocimiento de la dirección de correo electrónico Regexp duro?

En resumen, no se espera una sola, la expresión regular utilizable para hacer un trabajo adecuado. Y la mejor expresión regular validar la sintaxis, no la validez de un correo electrónico ([email protected] es correcta pero probablemente se recuperará ...).