¿Cuáles son las mejores prácticas para validar direcciones de correo electrónico en iOS 2.0?

167

¿Cuál es la forma más limpia de validar una dirección de correo electrónico que un usuario ingresa en iOS 2.0?

NOTA : Esta es una pregunta histórica que es específica de iOS 2.0 y debido a su antigüedad y a cuántas otras preguntas están vinculadas, no se puede retirar y NO DEBE cambiarse a una pregunta "moderna".

Marcus S. Zarra
fuente
Estoy buscando una solución de cacao. Entiendo la validez de los correos electrónicos y las reglas sobre la validación de correos electrónicos. Sin embargo, dado que RegEx no es fácilmente accesible en Cocoa Touch, estoy buscando una solución de Cocoa Touch para la validación. No es una lista de las reglas en torno a la validación.
Marcus S. Zarra
Hasta ahora, la mejor sugerencia de código que he encontrado es usar RegExKitLite y expresiones regulares. Afortunadamente es menos doloroso de lo que parece.
Marcus S. Zarra
Vea los comentarios a continuación sobre el uso de NSRegularExpression para aplicaciones que no son compatibles con os <4.0.
partir del
1
Dado que esta parece ser la pregunta canónica con respecto a la validación de la dirección de correo electrónico, tiene sentido actualizar con respuestas mejoradas a medida que iOS madura. Con eso en mente, he agregado una respuesta que usa iOS NSDataDetectorpara validar las direcciones de correo electrónico: stackoverflow.com/a/23547905/257550
memmons
2
Esta pregunta parece estar fuera de tema porque se trata de iOS 2.0, que fue obsoleto hace años.
Nathan Eror

Respuestas:

354

La respuesta a Usar una expresión regular para validar una dirección de correo electrónico explica con gran detalle que la gramática especificada en RFC 5322 es demasiado complicada para las expresiones regulares primitivas.

Recomiendo un enfoque de analizador real como MKEmailAddress .

Como solución rápida de expresiones regulares, vea esta modificación de DHValidation :

- (BOOL) validateEmail: (NSString *) candidate {
    NSString *emailRegex =
@"(?:[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])+)\\])"; 
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES[c] %@", emailRegex]; 

    return [emailTest evaluateWithObject:candidate];
}
Catlan
fuente
9
Genial, pero no funciona en SO <3.0, porque NSPredicate no está disponible.
Felixyz
44
Agradable. Todos olvidan que NSPredicate puede ejecutar expresiones regulares.
Rog
55
Esa es una muy mala expresión regular. Por ejemplo, fallará en las personas que usan el dominio superior .museum. Consulte este artículo: linuxjournal.com/article/9585
Jonny
18
Hay una expresión regular más completa en cocoawithlove.com/2009/06/... que se puede usar en lugar de esta simple.
Tomas Andrle
12
Aquí hay una expresión regular de correo electrónico muy ingenua pero liberal como una cadena de Cocoa: @"[^@]+@[^.@]+(\\.[^.@]+)+"si necesita verificar una dirección de correo electrónico, envíele un mensaje y vea si tiene éxito. Nunca lo verificará con ningún nivel de precisión solo con una expresión regular, por lo que es mejor no molestar a los usuarios y perder registros debido a una expresión regular innecesariamente estricta.
Sami Samhuri
20

Lee el RFC. Casi todos los que piensan que saben cómo analizar / limpiar / validar una dirección de correo electrónico están equivocados.

http://tools.ietf.org/html/rfc2822 La sección 3.4.1 es muy útil. aviso

dtext = NO-WS-CTL /; Controles sin espacios en blanco

                        % d33-90 /; El resto de los EE.UU.-ASCII
                        % d94-126; caracteres que no incluyen "[",
                                        ; "]" o "\"

Sí, eso significa que +, ', etc. son todos legítimos.

Trey
fuente
Actual a partir de mayo de 2016: RFC5322, sección 3.4.1
leanne
17

La mejor solución que he encontrado hasta ahora (y con la que terminé yendo) es agregar RegexKitLite al proyecto que da acceso a expresiones regulares a través de Categorías NSString.

Es bastante sencillo agregar al proyecto y una vez implementado, cualquiera de las lógicas de validación de correo electrónico de expresión regular funcionará.

Marcus S. Zarra
fuente
55
NSPredicate puede hacer RegEx sin agregar bibliotecas adicionales a su proyecto.
BadPirate
10
Esta pregunta, de abril de 2009, fue antes de que NSPredicate existiera en iOS.
Marcus S. Zarra
77
Nuevamente, NSRegularExpression NO EXISTE en iOS 2.0 cuando se hizo esta pregunta.
Marcus S. Zarra
9
@Marcus, el objetivo de Stack Overflow no es mantener un registro histórico de cómo se resolvieron problemas particulares en el pasado. Dicho esto, he editado su pregunta para enfatizar el ángulo de compatibilidad 2.0.
benzado
2
Lea el título, esto es para iOS 2.0, que la solución de Catlan no existía.
Marcus S. Zarra
10

Un buen comienzo es decidir qué quieres y qué no quieres aceptar como dirección de correo electrónico.

El 99% de las direcciones de correo electrónico se ven así: [email protected] o [email protected]

Sin embargo, técnicamente es legal tener una dirección de correo electrónico como esta: f !#$%&'*+-/=?^_{|} ~ "ha!" @ Com

Probablemente solo haya un puñado de correos electrónicos válidos en el mundo para dominios de nivel superior, y casi nadie usa la mayoría de esos otros caracteres (especialmente comillas y comillas), por lo que es posible que desee asumir que todas estas son cosas no válidas para hacer. Pero debe hacerlo como una decisión consciente.

Más allá de eso, haga lo que dice Paul e intente hacer coincidir la entrada con una expresión regular como esta: ^ [A-Z0-9 ._% + -] + @ [A-Z0-9 .-] +. [AZ] { 2,} $

Ese coincidirá con la dirección de correo electrónico de casi todos.

Brandon Yarbrough
fuente
a pesar de que esta respuesta fue escrita en 2009, todavía aparece muy alta en los resultados de búsqueda. Solo quería agregar que esto ya no está actualizado y que la expresión regular anterior es un poco restrictiva. por ejemplo, ahora puede tener un dominio de nivel superior de 4 dígitos o más
Jack
Buen punto, editado a "al menos 2 dígitos". Siéntase libre de editar más si lo desea.
Brandon Yarbrough
7

Si bien el enfoque en las expresiones regulares es bueno, este es solo un primer y necesario paso. Hay otros pasos que también deben tenerse en cuenta para una buena estrategia de validación.

Dos cosas encima de mi cabeza son:

  1. Validación de DNS para asegurarse de que el dominio realmente exista.

  2. Después de la validación dns, también puede optar por hacer una validación smtp. envíe una llamada al servidor smtp para ver si el usuario realmente existe.

De esta forma, puede detectar todo tipo de errores de usuario y asegurarse de que sea un correo electrónico válido.

Srikar Doddi
fuente
7

Esta función es simple y, sin embargo, verifica la dirección de correo electrónico más a fondo. Por ejemplo, de acuerdo con RFC2822, una dirección de correo electrónico no debe contener dos puntos seguidos, como el nombre de pila ... el nombre de pila @ dominio..com

También es importante usar anclas en expresiones regulares como se ve en esta función. Sin anclajes, la siguiente dirección de correo electrónico se considera válida: primer nombre; [email protected] (bla porque la sección [email protected] es válida, ignorando el primer nombre) al principio y (bla al final). motor de expresiones regulares para validar todo el correo electrónico.

Esta función utiliza NSPredicate, que no existe en iOS 2. Desafortunadamente, puede que no ayude al autor de la pregunta, pero con suerte ayudará a otros con versiones más recientes de iOS. Sin embargo, las expresiones regulares en esta función aún se pueden aplicar a RegExKitLite en iOS 2. Y para aquellos que usan iOS 4 o posterior, estas expresiones regulares se pueden implementar con NSRegularExpression.

- (BOOL)isValidEmail:(NSString *)email
{
    NSString *regex1 = @"\\A[a-z0-9]+([-._][a-z0-9]+)*@([a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,4}\\z";
    NSString *regex2 = @"^(?=.{1,64}@.{4,64}$)(?=.{6,100}$).*";
    NSPredicate *test1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex1];
    NSPredicate *test2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex2];
    return [test1 evaluateWithObject:email] && [test2 evaluateWithObject:email];
}

Vea validar la dirección de correo electrónico utilizando expresiones regulares en Objective-C .

Friki
fuente
iOS 2.0 no tenía NSPredicate.
Marcus S. Zarra
2
Pero, ¿para qué sirve esta pregunta y para qué sirve iOS 2. Estamos teniendo el último sistema operativo que es iOS 7.1. también puedes usar ios 6.
Gaurav Gilani
6
NSString *emailString = textField.text; **// storing the entered email in a string.** 
**// Regular expression to checl the email format.** 
NSString *emailReg = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; 
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",emailReg]; 
if (([emailTest evaluateWithObject:emailString] != YES) || [emailStringisEqualToString:@""]) 
{ 
UIAlertView *loginalert = [[UIAlertView alloc] initWithTitle:@" Enter Email in" message:@"[email protected] format" delegate:self 
cancelButtonTitle:@"OK" otherButtonTitles:nil]; 

enter code here

[loginalert show]; 
[loginalert release]; 
} 
If email is invalid, it will remind the user with an alert box. 
Hope this might be helpful for you all. 
hirak
fuente
4

He descubierto que usar una expresión regular funciona bastante bien para validar una dirección de correo electrónico.

El principal inconveniente de las expresiones regulares, por supuesto, es la facilidad de mantenimiento, así que comente como nunca lo ha hecho antes. Te lo prometo, si no lo haces, desearás haberlo hecho cuando vuelvas a la expresión después de unas semanas.

Aquí hay un enlace a una buena fuente, http://www.regular-expressions.info/email.html .

Paul Redman
fuente
Implementé el penúltimo en esa página recientemente, y estoy bastante contento con eso. Funciona bien para una simple dirección de correo electrónico [email protected], sin comillas ni corchetes para un nombre completo. Funciona muy bien para la validación de formularios web donde las personas no escribirán ese tipo de cosas de todos modos.
zombat
2
Pobres con su dominio .museum.
BadPirate
3

Desenterrando la tierra, pero me topé con SHEmailValidator que hace un trabajo perfecto y tiene una interfaz agradable.

Cirilo
fuente
Esta pregunta era específica para iOS 2.0 que no tenía NSPredicate o una gran cantidad de otras cosas que se estaban utilizando en esa biblioteca.
Marcus S. Zarra
1
Lo sé, pero llegué aquí primero mientras buscaba "validación de correo electrónico ios". Tal vez algún futuro yo realice la misma búsqueda y aterrice aquí y le ahorre algo de tiempo.
Cyrille
1

Muchos sitios web proporcionan RegExes, pero haría bien en aprenderlos y comprenderlos, así como verificar que lo que desea que haga satisfaga sus necesidades dentro del RFC oficial para formatos de dirección de correo electrónico.

Para aprender RegEx, los idiomas interpretados pueden ser un gran simplificador y un banco de pruebas. Rubular se basa en Ruby, pero es una buena forma rápida de probar y verificar: http://www.rubular.com/

Más allá de eso, compre la última edición del libro O'Reilly Mastering Regular Expressions. Querrá pasar el tiempo para comprender los primeros 3 o 4 capítulos. Todo después de eso será desarrollar experiencia en el uso de RegEx altamente optimizado.

A menudo, una serie de RegExes más pequeños y fáciles de administrar son más fáciles de mantener y depurar.

usuario656483
fuente
0

Aquí hay una extensión de String que valida un correo electrónico en Swift.

extension String {

    func isValidEmail() -> Bool {
        let stricterFilter = false
        let stricterFilterString = "^[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$"
        let laxString = "^.+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2}[A-Za-z]*$"
        let emailRegex = stricterFilter ? stricterFilterString : laxString
        let emailTest = NSPredicate(format: "SELF MATCHES %@", emailRegex)
        return emailTest.evaluate(with: self)
    }
}

Copiado de la respuesta a: Verifique que una dirección de correo electrónico sea válida en iOS

InnisBrendan
fuente
No hubo NSPredicateen iOS 2.0
Marcus S. Zarra
-2

No debe intentar utilizar expresiones regulares para validar un correo electrónico. Con los TLD que cambian constantemente, su validador es incompleto o inexacto. En su lugar, debe aprovechar las NSDataDetectorbibliotecas de Apple que tomarán una cadena e intentarán ver si hay campos de datos conocidos (correos electrónicos, direcciones, fechas, etc.). ¡El SDK de Apple hará todo lo posible por mantenerse al día con los TLD y usted puede aprovechar sus esfuerzos! :)

Además, si iMessage (o cualquier otro campo de texto) no cree que sea un correo electrónico, ¿debería considerar un correo electrónico?

Puse esta función en una NSStringcategoría, por lo que la cadena que está probando es self.

- (BOOL)isValidEmail {
    // Trim whitespace first
    NSString *trimmedText = [self stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
    if (self && self.length > 0) return NO;

    NSError *error = nil;
    NSDataDetector *dataDetector = [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink error:&error];
    if (!dataDetector) return NO;

    // This string is a valid email only if iOS detects a mailto link out of the full string
    NSArray<NSTextCheckingResult *> *allMatches = [dataDetector matchesInString:trimmedText options:kNilOptions range:NSMakeRange(0, trimmedText.length)];
    if (error) return NO;
    return (allMatches.count == 1 && [[[allMatches.firstObject URL] absoluteString] isEqual:[NSString stringWithFormat:@"mailto:%@", self]]);
}

o como una Stringextensión rápida

extension String {
    func isValidEmail() -> Bool {
        let trimmed = self.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty, let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
            return false
        }
        let allMatches = dataDetector.matches(in: trimmed, options: [], range: NSMakeRange(0, trimmed.characters.count))

        return allMatches.count == 1 && allMatches.first?.url?.absoluteString == "mailto:\(trimmed)"
    }
}
Señor t
fuente
1
Esta pregunta es de OCHO años atrás.
Marcus S. Zarra
1
Y sin embargo, si buscas en Google validate email objective-c, esta pregunta es el tercer resultado. Algunas cosas en internet no envejecen. :-)
Craig Otis
1
Deje de enviar spam a esta respuesta debajo de cada publicación que pueda encontrar que esté relacionada con la validación de direcciones de correo electrónico. Los comentarios son para solicitar aclaraciones, no para enviar spam a sus respuestas.
meagar
Por cierto, NSDataDetectorNO existía en iOS 2.0, que es de lo que se trataba esta pregunta.
Marcus S. Zarra
-7
// Method Call
NSString *email = @"Your Email string..";

BOOL temp = [self validateEmail:email];

if(temp)
{
// Valid
}
else
{
// Not Valid
}
// Method description

- (BOOL) validateEmail: (NSString *) email {
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    BOOL isValid = [emailTest evaluateWithObject:email];
    return isValid;
}
Gaurav Gilani
fuente
3
Este hilo / pregunta es para iOS 2. NSPredicateno existía en iOS 2; no se agregó hasta iOS 3.
Marcus S. Zarra
3
Respondí porque tu respuesta es incorrecta. La pregunta es "¿cómo haces X en iOS Y" y respondiste con un marco que no existe en esa versión de iOS.
Marcus S. Zarra