Escriba una función o programa para validar una dirección de correo electrónico contra RFC 5321 (algunas reglas gramaticales encontradas en 5322 ) con la tranquilidad de que puede ignorar comentarios y espacios en blanco plegables ( CFWS
) y literales de dirección generalizados. Esto le da a la gramática
Mailbox = Local-part "@" ( Domain / address-literal )
Local-part = Dot-string / Quoted-string
Dot-string = Atom *("." Atom)
Atom = 1*atext
atext = ALPHA / DIGIT / ; Printable US-ASCII
"!" / "#" / ; characters not including
"$" / "%" / ; specials. Used for atoms.
"&" / "'" /
"*" / "+" /
"-" / "/" /
"=" / "?" /
"^" / "_" /
"`" / "{" /
"|" / "}" /
"~"
Quoted-string = DQUOTE *QcontentSMTP DQUOTE
QcontentSMTP = qtextSMTP / quoted-pairSMTP
qtextSMTP = %d32-33 / %d35-91 / %d93-126
quoted-pairSMTP = %d92 %d32-126
Domain = sub-domain *("." sub-domain)
sub-domain = Let-dig [Ldh-str]
Let-dig = ALPHA / DIGIT
Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig
address-literal = "[" ( IPv4-address-literal / IPv6-address-literal ) "]"
IPv4-address-literal = Snum 3("." Snum)
IPv6-address-literal = "IPv6:" IPv6-addr
Snum = 1*3DIGIT
; representing a decimal integer value in the range 0 through 255
Nota: Me he saltado la definición de IPv6-addr
porque este RFC en particular se equivoca y no permite, por ejemplo ::1
. La especificación correcta está en RFC 2373 .
Restricciones
No puede usar ninguna llamada existente a la biblioteca de validación de correo electrónico. Sin embargo, puede usar las bibliotecas de red existentes para verificar las direcciones IP.
Si escribe una función / método / operador / equivalente, debe tomar una cadena y devolver un valor booleano o verdadero / falso, según corresponda para su idioma. Si escribe un programa, debe tomar una sola línea de stdin e indicar válido o no válido a través del código de salida.
Casos de prueba
Los siguientes casos de prueba se enumeran en bloques para compacidad. El primer bloque son casos que deben pasar:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
email@[123.123.123.123]
"email"@domain.com
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
""@domain.com
"e"@domain.com
"\@"@domain.com
email@domain
"Abc\@def"@example.com
"Fred Bloggs"@example.com
"Joe\\Blow"@example.com
"Abc@def"@example.com
customer/[email protected]
[email protected]
!def!xyz%[email protected]
[email protected]
_somename@[IPv6:::1]
[email protected]
[email protected]
[email protected]
Los siguientes casos de prueba no deben pasar:
plainaddress
#@%^%#$@#$@#.com
@domain.com
Joe Smith <[email protected]>
email.domain.com
email@[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected] (Joe Smith)
[email protected]
[email protected]
email@[IPv6:127.0.0.1]
email@[127.0.0]
email@[.127.0.0.1]
email@[127.0.0.1.]
email@IPv6:::1]
[email protected]]
email@[256.123.123.123]
fuente
IPv6-addr
se ha dejado sin definir, y hay casos de prueba que tienen direcciones ipv6, ¿hay alguna forma correcta de validarlos?[email protected]
y[email protected]
falla?Respuestas:
Python 3.3, 261
Python 3.3 es necesario para el módulo ipaddress, que se utiliza para validar las direcciones IPv4 e IPv6.
Versión menos golfizada:
fuente
ALPHA
en BNF aumentado y los literales char que construyen a noQuoted-string
distinguen entre mayúsculas y minúsculas. ¿Puedes depilar algunos caracteres especificando mayúsculas y minúsculas y deshaciéndote de uno de esos rangos de clases de caracteres? por cierto, si te sientes juguetón, ¿puedes dar una breve descripción de cómo desarrollaste esto?PHP 5.4.9, 495
Y para mayor interés, aquí hay uno para la gramática RFC 5322 que permite CFWS anidados y partes locales obsoletas:
(764)
Y si los límites de longitud no son un requisito:
RFC 5321 (414)
RFC 5322 (636)
fuente