2010-12-01 11 views
8

Todos sabemos que una expresión regular para validar correctamente los correos electrónicos sería quite complicated. Sin embargo, el plugin de validación de jQuery tiene una expresión regular más corto (aportado por Scott Gonzalez), que abarca sólo unas pocas líneas:¿Por qué es tan simple la validación de correo electrónico de jQuery regex?

/^((([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])))\.?$/ 

Por qué es tan 'simple' en comparación con la monstruosidad más conocida? ¿Hay casos en que una expresión regular fallaría y la otra tendría éxito (independientemente de si los correos electrónicos son válidos o no válidos)?

+12

Simple no es la palabra que usaría para esa expresión regular;) – JaredPar

+4

* Ahem * ¿Simple? Si esa expresión regular es simple, ¿qué clasificaría como complicado? – Alex

+0

Hable sobre pisando en el territorio de lenguaje de solo escritura ... – Serguei

Respuesta

10

La expresión regular es una combinación personalizada de:

  • RFC 2234 ABNF
  • RFC 2396 URI Sintaxis Genérica (obseleted por RFC 3986)
  • RFC 2616 Hypertext Transfer Protocol - HTTP/1.1
  • RFC 2822 Formato de mensajes de Internet
  • RFC 3987 IRI
  • RFC 3986 URI sintaxis genérica

Escribí la expresión regular cuando se estaba redactando y RFC 5322 no existía. Si observa el orden en que se escribieron los RFC, notará que la definición de IRI y URI cambió después de que se escribió el Formato de mensaje de Internet. Esto significa que RFC 2822 no es compatible con las definiciones actuales de IRI. Desafortunadamente, no era una tarea simple de solo sustituir definiciones, así que tuve que escoger y elegir qué definiciones usar de las RFC. También tomé decisiones sobre qué eliminar (como soporte para comentarios).

La expresión regular no está completamente escrita a mano. Mientras escribía manualmente cada sección de la expresión regular, escribí el "pegamento". Cada definición de las RFC se almacena en una variable, con definiciones compuestas que utilizan las variables que almacenan las definiciones más simples (@Walf: esta es la razón por la que hay tantos subpatrones y ors).

Para complicar el asunto, la versión de la expresión regular que se utiliza en el complemento jQuery Validation se modifica aún más para tener en cuenta las diferencias entre las direcciones válidas y la expectativa del usuario de una dirección válida. No recuerdo qué modificaciones hice. Le prometí a Jörn Zaefferer (el autor del complemento de validación) que escribiría un script más nuevo para generar la expresión regular. La nueva secuencia de comandos le permitirá especificar opciones para lo que hace y no desea apoyar (TLD requerido, TLD específicos, IPv6, comentarios, definiciones obsoletas, nombres locales entrecomillados, etc.). Eso fue hace 5 años. Lo comencé una vez, pero nunca terminé. Tal vez algún día lo haga. Lo que tenemos hasta el momento se encuentra alojado en GitHub: https://github.com/scottgonzalez/regex-builder

Si desea una expresión regular para validar direcciones de correo electrónico, me gustaría sugerir la siguiente expresión regular que se incluye en el HTML5 specification:

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

Si usa regex-builder y apaga todas las opciones, obtendrás algo similar. Pero ha pasado un año desde que miré eso, así que no recuerdo cuáles son las diferencias.


También me gustaría señalar que el enlace en la pregunta original menciona específicamente el RFC 822. Si bien es muy bueno que nos RFC 822 avanzó de Arpanet a la ARPA Internet, esto no es exactamente actual. Internet ha logrado algunos avances en las últimas tres décadas y este RFC ha sido reemplazado dos veces. Me gustaría ver cualquier trabajo nuevo siguiendo los últimos estándares.


ACTUALIZACIÓN:

Un amigo me preguntó por qué la expresión regular HTML5 no soporta UTF-8. Nunca le pregunté a Hixie al respecto, pero supongo que esta es la razón: aunque algunos TLD comenzaron a admitir IDN (Nombres de dominio internacionales) en 2000 y RFC 3987 (IRI) se escribió en 2005, cuando se redactó RFC 5322 en 2008. solo incluyó caracteres en los rangos 33-90 y 94-126 como dtext válido (caracteres permitidos para uso en un dominio literal). HTML5 está basado en RFC 5322 y como resultado no hay soporte UTF-8. Ciertamente, parece extraño que RFC 5322 no tenga en cuenta los IDN, pero no vale la pena que incluso en 2008 los IDN no se puedan utilizar realmente. No fue sino hasta 2010 que la ICANN aprobó el primer conjunto de IDN. Sin embargo, incluso hoy, si desea usar un IDN, necesita destruir completamente su nombre de dominio con Punycode si realmente desea que cosas como el correo electrónico y el DNS funcionen globalmente.

ACTUALIZACIÓN 2:

Actualización regex HTML5 para que coincida con la especificación actualizada, que cambió límites de longitud de la etiqueta de 255 caracteres a 63 caracteres, como se especifica en RFC 1034 section 3.5.

+0

La página de especificaciones HTML5 tiene una versión ligeramente diferente a este patrón; tal vez ha sido actualizado? Principalmente limita las secciones a 63 (denominadas etiquetas en las RFC). También evita que se termine una etiqueta con un guión. – goodeye

+0

Dado que la pila y la wikipedia siguen haciendo referencia entre sí, encontré algunos buenos resúmenes aquí: http://blog.sacaluta.com/2011/12/dns-domain-names-253-or-255-bytesoctets.html y http://blogs.msdn.com/b/oldnewthing/archive/2012/04/12/10292868.aspx – goodeye

+0

@goodeye Gracias por señalarlo. Actualicé la expresión regular, aunque no hubo cambios para las terminaciones de las etiquetas, solo longitud. –

1

Eso no se ve bien: ¿qué pasa con el Unicode? ¿Con qué RFC se está validando esto?

Consulte this answer para obtener una expresión regular RFC5322-validating.

+0

Tampoco me parece correcto; de ahí la pregunta. Esto se toma directamente de un archivo marcado como '$ Id: jquery.validate.js 6403 2009-06-17 14: 27: 16Z joern.zaefferer $ 'línea 1011. – configurator

Cuestiones relacionadas