Quelles sont les meilleures pratiques pour valider les adresses e-mail sur iOS 2.0

167

Quelle est la manière la plus propre de valider une adresse e-mail saisie par un utilisateur sur iOS 2.0?

REMARQUE : Il s'agit d'une question historique spécifique à iOS 2.0 et en raison de son âge et du nombre d'autres questions qui y sont liées, elle ne peut pas être retirée et NE DOIT PAS être remplacée par une question "moderne".

Marcus S. Zarra
la source
Je recherche une solution de cacao. Je comprends la validité des e-mails et les règles de validation des e-mails. Cependant comme RegEx n'est pas facilement accessible sur Cocoa Touch, je recherche une solution Cocoa Touch à validation. Pas une liste des règles autour de la validation.
Marcus S.Zarra
Jusqu'à présent, la meilleure suggestion de code que j'ai trouvée est l'utilisation de RegExKitLite et des expressions régulières. Heureusement, c'est moins douloureux qu'il n'y paraît.
Marcus S.Zarra
Voir les commentaires ci-dessous sur l'utilisation de NSRegularExpression pour les applications ne prenant pas en charge os <4.0.
beOn
1
Comme cela semble être la question canonique concernant la validation des adresses e-mail, il est logique de mettre à jour avec des réponses améliorées à mesure que iOS mûrit. Dans cet esprit, j'ai ajouté une réponse qui utilise iOS NSDataDetectorpour valider les adresses e-mail: stackoverflow.com/a/23547905/257550
memmons
2
Cette question semble être hors sujet car elle concerne iOS 2.0 qui était obsolète il y a des années.
Nathan Eror

Réponses:

354

La réponse à Utiliser une expression régulière pour valider une adresse e-mail explique en détail que la grammaire spécifiée dans la RFC 5322 est trop compliquée pour les expressions régulières primitives.

Je recommande une véritable approche parseur comme MKEmailAddress .

Comme solution rapide d'expressions régulières, voyez cette modification 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
la source
9
Excellent mais ne fonctionne pas sur OS <3.0, car NSPredicate n'est pas disponible.
Felixyz
4
Agréable. Tout le monde oublie que NSPredicate peut exécuter des expressions régulières.
Rog
5
C'est une très mauvaise expression rationnelle. Par exemple, il échouera sur les personnes utilisant le domaine principal .museum. Reportez-vous à cet article: linuxjournal.com/article/9585
Jonny
18
Il y a une regex plus complète sur cocoawithlove.com/2009/06/… qui peut être utilisée à la place de celle-ci simple.
Tomas Andrle
12
Voici une expression régulière de courrier électronique très naïve mais libérale sous forme de chaîne Cocoa: @"[^@]+@[^.@]+(\\.[^.@]+)+"Si vous avez besoin de vérifier une adresse électronique, envoyez-lui un message et voyez si cela réussit. Vous ne le vérifierez jamais avec un niveau de précision avec un regex seul, il est donc préférable de ne pas pisser les utilisateurs et de perdre les inscriptions à cause d'un regex inutilement strict.
Sami Samhuri
20

Lisez la RFC. Presque tous ceux qui pensent savoir comment analyser / nettoyer / valider une adresse e-mail se trompent.

http://tools.ietf.org/html/rfc2822 La section 3.4.1 est très utile. Remarquer

dtext = NO-WS-CTL /; Commandes sans espace blanc

                        % d33-90 /; Le reste de l'US-ASCII
                        % d94-126; caractères sans "[",
                                        ; "]", ou "\"

Oui, cela signifie que +, ', etc. sont tous légitimes.

Trey
la source
À jour en mai 2016: RFC5322, section 3.4.1
leanne
17

La meilleure solution que j'ai trouvée jusqu'à présent (et celle avec laquelle j'ai fini par aller) est d'ajouter RegexKitLite au projet qui donne accès aux expressions régulières via NSString Categories.

Il est assez facile d'ajouter au projet et une fois en place, n'importe quelle logique de validation de courrier électronique d'expression régulière fonctionnera.

Marcus S. Zarra
la source
5
NSPredicate peut faire RegEx sans ajouter de bibliothèques supplémentaires à votre projet.
BadPirate
10
Cette question, d'avril 2009, était avant que NSPredicate n'existe sur iOS.
Marcus S.Zarra
7
Encore une fois, NSRegularExpression N'EXISTE PAS dans iOS 2.0 lorsque cette question a été posée.
Marcus S.Zarra
9
@Marcus, le but de Stack Overflow n'est pas de conserver un historique de la façon dont des problèmes particuliers ont été résolus dans le passé. Cela dit, j'ai modifié votre question pour souligner l'angle de compatibilité 2.0.
benzado
2
Veuillez lire le titre, c'est pour iOS 2.0 dont la solution Catlan n'existait pas.
Marcus S.Zarra
10

Un bon début est de décider ce que vous et ne voulez pas accepter comme adresse e-mail?

99% des adresses e-mail ressemblent à ceci: [email protected] ou [email protected]

Cependant, il est techniquement légal d'avoir une adresse e-mail comme celle-ci: f !#$%&'*+-/=?^_{|} ~ "ha!" @ Com

Il n'y a probablement qu'une poignée d'e-mails valides dans le monde pour les domaines de premier niveau, et presque personne n'utilise la plupart de ces autres caractères (en particulier les guillemets et les crochets), vous voudrez peut-être supposer que ce sont toutes des choses invalides à faire. Mais vous devez le faire par décision consciente.

Au-delà de cela, faites ce que Paul dit et essayez de faire correspondre l'entrée à une expression régulière comme celle-ci: ^ [A-Z0-9 ._% + -] + @ [A-Z0-9 .-] +. [AZ] { 2,} $

Celui-ci correspondra à l'adresse e-mail de presque tout le monde.

Brandon Yarbrough
la source
même si cette réponse a été écrite en 2009, elle occupe toujours une place très importante dans les résultats de recherche. Je voulais juste ajouter que ce n'est plus à jour et que le regex ci-dessus est un peu restrictif. par exemple, vous pouvez maintenant avoir un domaine de premier niveau à 4 chiffres ou plus
Jack
Bon point, édité à "au moins 2 chiffres". N'hésitez pas à modifier davantage si vous le souhaitez.
Brandon Yarbrough
7

Bien que l'accent soit mis sur les expressions régulières, il est bon, mais ce n'est qu'une première étape nécessaire. Il y a d'autres étapes qui doivent également être prises en compte pour une bonne stratégie de validation.

Deux choses sur ma tête sont:

  1. Validation DNS pour s'assurer que le domaine existe réellement.

  2. Après la validation DNS, vous pouvez également choisir de faire une validation smtp. envoyer un appel au serveur smtp pour voir si l'utilisateur existe réellement.

De cette façon, vous pouvez détecter toutes sortes d'erreurs utilisateur et vous assurer qu'il s'agit d'un e-mail valide.

Srikar Doddi
la source
7

Cette fonction est simple et vérifie encore plus soigneusement l'adresse e-mail. Par exemple, selon la RFC2822, une adresse e-mail ne doit pas contenir deux points d'affilée, comme prénom..nom @ domaine..com

Il est également important d'utiliser des ancres dans les expressions régulières comme vu dans cette fonction. Sans ancres, l'adresse e-mail suivante est considérée comme valide: prénom; nom) [email protected] (bla parce que la section [email protected] est valide, ignorant le premier; nom) au début et (bla à la fin. Les ancres forcent le moteur d'expressions régulières pour valider l'intégralité de l'e-mail.

Cette fonction utilise NSPredicate qui n'existe pas dans iOS 2. Malheureusement, cela n'aidera peut-être pas le demandeur, mais avec un peu de chance, cela aidera les autres avec les nouvelles versions d'iOS. Les expressions régulières de cette fonction peuvent cependant être appliquées à RegExKitLite dans iOS 2. Et pour ceux qui utilisent iOS 4 ou version ultérieure, ces expressions régulières peuvent être implémentées avec 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];
}

Voir valider l'adresse e-mail à l'aide d'une expression régulière dans Objective-C .

Geek
la source
iOS 2.0 n'avait pas NSPredicate.
Marcus S.Zarra
2
Mais quelle est l'utilité de cette question et quelle est l'utilité d'ios 2. Nous avons le dernier os qui est ios 7.1. vous pouvez également utiliser 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
la source
4

J'ai trouvé que l'utilisation d'une expression régulière fonctionne assez bien pour valider une adresse e-mail.

Le principal inconvénient des expressions régulières est bien sûr la maintenabilité, alors commentez comme vous ne l'avez jamais fait auparavant. Je vous le promets, si vous ne le faites pas, vous souhaiteriez que vous le fassiez lorsque vous reviendrez à l'expression après quelques semaines.

Voici un lien vers une bonne source, http://www.regular-expressions.info/email.html .

Paul Redman
la source
J'ai récemment implémenté l'avant-dernier sur cette page, et j'en suis très satisfait. Cela fonctionne bien pour une simple adresse e-mail [email protected], sans guillemets ni crochets pour un nom complet. Fonctionne très bien pour la validation de formulaire Web où les gens ne taperont pas ce genre de chose de toute façon.
zombat
2
Les pauvres avec leur TLD .museum.
BadPirate
3

Creuser la saleté, mais je suis juste tombé sur SHEmailValidator qui fait un travail parfait et a une belle interface.

Cyrille
la source
Cette question était spécifique à iOS 2.0 qui n'avait pas NSPredicate ou toute une foule d'autres choses qui sont utilisées dans cette bibliothèque.
Marcus S.Zarra
1
Je sais, mais j'ai atterri ici en premier en cherchant "validation d'e-mail ios". Peut-être qu'un futur moi effectuera la même recherche et atterrira ici et cela lui fera gagner du temps.
Cyrille
1

De nombreux sites Web fournissent des RegExes, mais vous feriez bien de les apprendre et de les comprendre, ainsi que de vérifier que ce que vous voulez qu'il fasse répond à vos besoins dans le RFC officiel pour les formats d'adresses e-mail.

Pour apprendre RegEx, les langues interprétées peuvent être un excellent simplificateur et un banc d'essai. Rubular est construit sur Ruby, mais c'est un bon moyen rapide de tester et de vérifier: http://www.rubular.com/

Au-delà de cela, achetez la dernière édition du livre O'Reilly Mastering Regular Expressions. Vous voudrez passer le temps à comprendre les 3 ou 4 premiers chapitres. Tout après cela renforcera l'expertise sur une utilisation RegEx hautement optimisée.

Souvent, une série de RegEx plus petits et plus faciles à gérer sont plus faciles à maintenir et à déboguer.

utilisateur656483
la source
0

Voici une extension de String qui valide un e-mail dans 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)
    }
}

Copié de la réponse vers: vérifier qu'une adresse e-mail est valide sur iOS

InnisBrendan
la source
Il n'y avait pas NSPredicatesur iOS 2.0
Marcus S.Zarra
-2

Vous ne devriez pas essayer d'utiliser regex pour valider un e-mail. Avec des TLD en constante évolution, votre validateur est incomplet ou inexact. Au lieu de cela, vous devriez tirer parti des NSDataDetectorbibliothèques Apple qui prendront une chaîne et essayer de voir s'il existe des champs de données connus (e-mails, adresses, dates, etc.). Le SDK d'Apple fera le gros du travail pour rester à jour avec les TLD et vous pourrez profiter de leurs efforts! :)

De plus, si iMessage (ou tout autre champ de texte) ne pense pas qu'il s'agit d'un e-mail, devriez-vous envisager un e-mail?

J'ai mis cette fonction dans une NSStringcatégorie, donc la chaîne que vous testez est 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]]);
}

ou comme Stringextension rapide

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)"
    }
}
M. T
la source
1
Cette question date d'il y a HUIT ans.
Marcus S.Zarra
1
Et pourtant, si vous Google validate email objective-c, cette question est le troisième résultat. Certaines choses sur Internet ne vieillissent pas. :-)
Craig Otis
1
Veuillez arrêter de spammer les liens vers cette réponse sous chaque message que vous pouvez trouver et qui est lié à la validation des adresses e-mail. Les commentaires sont destinés à demander des éclaircissements, pas à envoyer des liens de spam vers vos réponses.
meagar
BTW, NSDataDetectorn'existait PAS dans iOS 2.0, c'est ce que cette question était / concerne.
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
la source
3
Ce fil / cette question concerne iOS 2. NSPredicaten'existait pas dans iOS 2; il n'a pas été ajouté avant iOS 3.
Marcus S. Zarra
3
J'ai répondu parce que votre réponse est fausse. La question est "comment faites-vous X sur iOS Y" et vous avez répondu avec un framework qui n'existe pas sur cette version d'iOS.
Marcus S.Zarra