Comment valider une adresse e-mail en swift?

338

Est-ce que quelqu'un sait comment valider une adresse e-mail dans Swift? J'ai trouvé ce code:

- (BOOL) validEmail:(NSString*) emailString {

    if([emailString length]==0){
        return NO;
    }

    NSString *regExPattern = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";

    NSRegularExpression *regEx = [[NSRegularExpression alloc] initWithPattern:regExPattern options:NSRegularExpressionCaseInsensitive error:nil];
    NSUInteger regExMatches = [regEx numberOfMatchesInString:emailString options:0 range:NSMakeRange(0, [emailString length])];

    NSLog(@"%i", regExMatches);
    if (regExMatches == 0) {
        return NO;
    } else {
        return YES;
    }
}

mais je ne peux pas le traduire en Swift.

Giorgio Nocera
la source
8
la traduction doit être simple. quelle partie vous pose des problèmes?
Sulthan
12
N'oubliez pas de prier qu'aucun de vos utilisateurs ne possède l'un des nouveaux domaines de premier niveau. Par exemple.coffee
Matthias Bauch
1
@Antzi: J'ai vérifié avec "quelqu'un @ gmail" et votre expression rationnelle est retournée vraie.
Đông An
2
Les expressions régulières ne fonctionnent pas pour valider que les utilisateurs ont entré leur adresse e-mail. La seule façon correcte à 100% est d'envoyer un e-mail d'activation. Voir: Je savais comment valider une adresse e-mail jusqu'à ce que je
lise le
2
C'est un AQ fascinant. Il s'agit presque certainement de l'assurance qualité la plus «erronée» sur l'ensemble du site. La réponse actuellement n ° 1 avec 600 votes (quoi?!) Est absolument, totalement, fausse de toutes les manières possibles (chaque ligne individuelle est complètement fausse, et chaque concept et idée est faux ........ !!!) Bon nombre des autres réponses très votées sont soit «complètement fausses», «extrêmement étouffantes», soit tout simplement brisées et ne compilent même pas. De plus, bien que la nature de ce Q appelle à «l'ingénierie des regex d'élite», de nombreuses réponses (très votées!) Présentent une ingénierie des regex épouvantable. C'est un QA vraiment intéressant !! Pourquoi??
Fattie

Réponses:

769

J'utiliserais NSPredicate:

func isValidEmail(_ email: String) -> Bool {        
    let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"

    let emailPred = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
    return emailPred.evaluate(with: email)
}

pour les versions de Swift antérieures à 3.0:

func isValidEmail(email: String) -> Bool {
    let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"

    let emailPred = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
    return emailPred.evaluate(with: email)
}

pour les versions de Swift antérieures à 1.2:

func isValidEmail(email: String) -> Bool {
    let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"

    if let emailPred = NSPredicate(format:"SELF MATCHES %@", emailRegEx) {
        return emailPred.evaluateWithObject(email)
    }
    return false
}
Maxim Shoustin
la source
6
ne serait pas return emailTest.evaluateWithObject(testStr)beaucoup plus simple et lisible? La comparaison avec == trueest un peu comme Javascript.
Sulthan
15
Il ne vérifie pas s'il y a une extension disponible, un @ a est déjà OK :(
CularBytes
6
cela ne valide pas pour test @ test ... com
Alan
3
Cela ne détecte pas les e-mails. @ Invalid.com ou e-mail @ .invalid.com. La réponse ci-dessous de @alexcristea le fait
Ben Sullivan
3
C'est assez drôle que ............ ainsi que (1) l'expression régulière soit totalement incorrecte (2) l'expression régulière (même dans le contexte de ce qu'elle essaie de faire) comporte des erreurs majeures ( 3) le Swift a tort (4) même en mettant cela de côté, le style est totalement faux (5) non pas qu'il compte compte tenu de tout le reste, mais il ne mentionne même pas que vous devez mettre en cache le prédicat ... avec humour, ( 6) il reste du code ("calendrier" - quoi?) D'où il a été copié.
Fattie
115

Modification, mise à jour pour Swift 3:

func validateEmail(enteredEmail:String) -> Bool {

    let emailFormat = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
    let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailFormat)
    return emailPredicate.evaluate(with: enteredEmail)

}

Réponse originale pour Swift 2:

func validateEmail(enteredEmail:String) -> Bool {

    let emailFormat = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
    let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailFormat)
    return emailPredicate.evaluateWithObject(enteredEmail)

}

Ça marche bien.

Azik Abdullah
la source
2
le premier avec une expression rationnelle valide. les autres valident aa @ aach à true
netshark1000
1
@ netshark1000, uniquement avec des votes positifs, toute réponse sera au top. :)
Azik Abdullah
NSRegularExpression est plus simple à utiliser que NSPredicate
Guillaume Laurent
1
Il ne gère pas la condition des deux points après le nom de domaine. essayez cette réponse stackoverflow.com/a/53441176/5032981
Prashant Gaikwad
@AzikAbdullah Si vous entrez «abc @ gmail..com», cela validera également
Nij
110

Comme Stringextension de classe

SWIFT 4

extension String {
    func isValidEmail() -> Bool {
        // here, `try!` will always succeed because the pattern is valid
        let regex = try! NSRegularExpression(pattern: "^[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])?)*$", options: .caseInsensitive)
        return regex.firstMatch(in: self, options: [], range: NSRange(location: 0, length: count)) != nil
    }
}

Usage

if "rdfsdsfsdfsd".isValidEmail() {

}
Arsonik
la source
4
countElementsest maintenantcount
Zack Shapiro
25
xxx @ yyy retourne vrai?
Cullen SUN
1
Identique à Cullen SUN, foo @ bar return true.
Rémy Virin
3
user @ host without .tld est également une adresse e-mail valide, par exemple root @ localhost
mer
1
Notez que la propriété NSRange length doit utiliser String utf16.count au lieu de characters.count
Leo Dabus
64

Si vous recherchez une solution propre et simple pour ce faire, vous devriez jeter un œil à https://github.com/nsagora/validation-components .

Il contient un prédicat de validation d'email qui est facile à intégrer dans votre code:

let email = "[email protected]"
let rule = EmailValidationPredicate()
let isValidEmail = rule.evaluate(with: email)

Derrière le capot, il utilise le RFC 5322 reg ex ( http://emailregex.com ):

let regex = "(?:[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}" +
    "~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\" +
    "x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\p{L}0-9](?:[a-" +
    "z0-9-]*[\\p{L}0-9])?\\.)+[\\p{L}0-9](?:[\\p{L}0-9-]*[\\p{L}0-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]?|[\\p{L}0-9-]*[\\p{L}0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21" +
    "-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"
alexcristea
la source
3
Wow, je ne connaissais pas emailregex.com. C'est génial!
Samuel Ev
2
Enfin, celui qui filtre les e-mails. @ .Mail.com
Ben Sullivan
cela fonctionne avec exact - [email protected]. ce n'est pas valider abc @ abc
Anil Gupta
Ah, enfin ..: D
Ümañg ßürmån
39

Voici la solution raisonnable:

"LA SOLUTION RAISONNABLE"

Utilisé et testé pendant des années dans de nombreuses applications à volume énorme.

1 - cela évite les nombreuses erreurs de regex terribles que vous voyez souvent dans ces suggestions

2 - il n'autorise PAS les e-mails stupides tels que "x @ x" qui sont considérés comme valides sous certains RFC, mais qui sont complètement stupides, ne peuvent pas être utilisés comme e-mails, et que votre personnel de support rejetterait instantanément, et que tous les services de messagerie (mailchimp, google, aws, etc.) refusent tout simplement. Si (pour une raison quelconque) vous avez besoin d'une solution qui autorise des chaînes telles que 'x @ x', utilisez une autre solution.

3 - le code est très, très, très compréhensible

4 - il est KISS, fiable et testé à la destruction sur les applications commerciales avec un grand nombre d'utilisateurs

5 - un point technique, le prédicat est un global, comme Apple le dit (faites attention aux suggestions de code qui ne l'ont pas)

let __firstpart = "[A-Z0-9a-z]([A-Z0-9a-z._%+-]{0,30}[A-Z0-9a-z])?"
let __serverpart = "([A-Z0-9a-z]([A-Z0-9a-z-]{0,30}[A-Z0-9a-z])?\\.){1,5}"
let __emailRegex = __firstpart + "@" + __serverpart + "[A-Za-z]{2,8}"
let __emailPredicate = NSPredicate(format: "SELF MATCHES %@", __emailRegex)

extension String {
    func isEmail() -> Bool {
        return __emailPredicate.evaluate(with: self)
    }
}

extension UITextField {
    func isEmail() -> Bool {
        return self.text!.isEmail()
    }
}

C'est si facile.

Explication:

Dans la description suivante, "OC" signifie un caractère ordinaire - une lettre ou un chiffre.

__firstpart ... doit commencer et se terminer par un OC. Pour les caractères du milieu, vous pouvez avoir certains caractères tels que le trait de soulignement, mais le début et la fin doivent être un OC. (Cependant, c'est ok d'avoir un seul OC et c'est tout, par exemple: [email protected])

__serverpart ... Vous avez des sections comme "blah". qui se répètent . (Donc type de chose mail.city.fcu.edu.) Les sections doivent commencer et se terminer par un OC, mais au milieu vous pouvez également avoir un tiret "-". (Si vous souhaitez autoriser d' autres caractères inhabituels, peut-être le trait de soulignement, ajoutez-le simplement avant le tiret.) C'est OK d'avoir une section qui n'est qu'un OC. (Comme dans [email protected]) Vous pouvez avoir jusqu'à cinq sections, vous devez en avoir une. Enfin , le TLD (.com) est strictement 2 à 8 en taille. Évidemment, changez simplement ce "8" selon les préférences de votre service d'assistance.


IMPORTANT!

Vous devez conserver le prédicat en tant que global, ne pas le construire à chaque fois.

Notez que c'est la première chose qu'Apple mentionne sur tout le problème dans les documents.

C'est très surprenant lorsque vous voyez des suggestions qui ne mettent pas en cache le prédicat.

Fattie
la source
1
Prend-il en charge les nouveaux TLD comme .engineer?
Roman
salut @Roman - remarquez où il est clairement dit "Enfin, le TLD (.com ou similaire) est strictement de 2 à 8 lettres." Cela s'en occupe. Vous pouvez changer le "8" en une valeur que vous préférez. (Pour l'instant, dans de nombreuses grandes entreprises, le service client rejettera tout long TLD comme une simple arnaque - mais de toute façon, c'est votre décision, utilisez "8" ou toute valeur que vous aimez.)
Fattie
2
En ce qui concerne le point (4): comment avez-vous testé avec beaucoup d'utilisateurs? Avez-vous suivi les utilisateurs qui ne pouvaient pas s'inscrire avec les applications commerciales, car l'expression régulière les empêchait d'utiliser leur adresse e-mail? Le seul "raisonnable" devrait être, ce que la spécification (RFC) spécifie ou si cela ne peut pas être atteint, alors quelque chose de plus détendu, mais qui couvre tout de la spécification. Si les utilisateurs ne sont pas autorisés à entrer x @ x, ils entreront un [email protected] qui transmettra votre / toute expression régulière.
thetrutz
salut @thetrutz, "[email protected]" est une adresse e-mail tout à fait normale. le RFC inclut une idiotie théorique comme "x @ x". tout client commercial réel pour lequel vous ou moi travaillons dira «interdire ceux-ci». (notez que dans toute grande entreprise du monde réel, il y a beaucoup plus de restrictions que mes grandes lignes ici, comme je le mentionne dans le commentaire ci-dessus à Roman.) Votre dernière phrase prête à confusion - bien sûr, un "e-mail non fonctionnel" passera test local? Que voulez-vous dire? De toute évidence, les e-mails ne sont finalement vérifiés que par le biais des systèmes "confirmer votre e-mail".
Fattie
Dans Swift, il est nécessaire d'optimiser chaque processus car nous utilisons généralement cette langue côté serveur.
Nicolas Manzini
25

Voici un fusible des deux réponses les plus votées avec l'expression rationnelle correcte: une extension de chaîne utilisant un prédicat afin que vous puissiez appeler string.isEmail

    extension String {
        var isEmail: Bool {
           let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,20}"            
           let emailTest  = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
           return emailTest.evaluateWithObject(self)
        }
    }
Nicolas Manzini
la source
19

Le moyen le plus simple dans Swift 5

extension String {
    var isValidEmail: Bool {
        NSPredicate(format: "SELF MATCHES %@", "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}").evaluate(with: self)
    }
}

Exemple

"[email protected]".isValidEmail

Retour...

true
Ken Mueller
la source
2
quel est l'intérêt de répéter la réponse répétée? qui ne dépend d'aucune des fonctionnalités de Swift 5
rommex
18

Je suggère de l'utiliser comme une extension de String:

extension String {    
    public var isEmail: Bool {
        let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)

        let firstMatch = dataDetector?.firstMatch(in: self, options: NSRegularExpression.MatchingOptions.reportCompletion, range: NSRange(location: 0, length: length))

        return (firstMatch?.range.location != NSNotFound && firstMatch?.url?.scheme == "mailto")
    }

    public var length: Int {
        return self.characters.count
    }
}

Et pour l'utiliser:

if "[email protected]".isEmail { // true
    print("Hold the Door")
}
JeffersonBe
la source
1
Notez que la propriété de longueur NSRange doit utiliser String utf16.count au lieu de characters.count
Leo Dabus
Mettre à jour Swift 4: extension String {public var isEmail: Bool {let dataDetector = try? NSDataDetector (types: NSTextCheckingResult.CheckingType.link.rawValue) let firstMatch = dataDetector? .FirstMatch (in: self, options: NSRegularExpression.MatchingOptions.reportCompletion, range: NSRange (location: 0, length: count)) return (firstMatch ?. range.location! = NSNotFound && firstMatch? .url? .scheme == "mailto")}
Duan Nguyen
15

Ceci est la version mise à jour pour Swift 2.0 - 2.2

 var isEmail: Bool {
    do {
        let regex = try NSRegularExpression(pattern: "^[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])?)*$", options: .CaseInsensitive)
        return regex.firstMatchInString(self, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, self.characters.count)) != nil
    } catch {
        return false
    }
}
Joel García Verástica
la source
8
foo @ bar renvoie vrai?!
Rémy Virin
2
valide aa @ aach sur true
netshark1000
4
C'est parce que le RFC valide ces adresses e-mail à true;)
dulgan
Notez que la propriété de longueur NSRange doit utiliser String utf16.count au lieu de characters.count
Leo Dabus
il est vraiment mauvais / médiocre de ne pas mettre en cache le prédicat. c'est la première chose qu'Apple dit à propos du problème dans le doco. une erreur flagrante commise par la plupart des réponses sur la page.
Fattie
9

Il y a beaucoup de bonnes réponses ici, mais beaucoup de "regex" sont incomplètes et il peut arriver qu'un email comme: "nom @ domaine" donne un email valide, mais ce n'est pas le cas. Voici la solution complète:

extension String {

    var isEmailValid: Bool {
        do {
            let regex = try NSRegularExpression(pattern: "(?:[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])+)\\])", options: .CaseInsensitive)
            return regex.firstMatchInString(self, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, self.characters.count)) != nil
        } catch {
            return false
        }
    }
}
Andrea.Ferrando
la source
ne fonctionne pas correctement, il vous permet d'ajouter des espaces après le domaine.
Juan Boero
Notez que la propriété de longueur NSRange doit utiliser String utf16.count au lieu de characters.count
Leo Dabus
@Fattie soutient votre déclaration. Votre commentaire est très inutile, suggérez une amélioration, proposez un correctif. Dire complètement faux est très stupide et sous-tend une mentalité étroite
Andrea.Ferrando
"Il y a beaucoup de bonnes réponses ici", cette phrase est spectaculairement incorrecte :) :)
Fattie
8

Voici une méthode basée sur rangeOfString:

class func isValidEmail(testStr:String) -> Bool {
    let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
    let range = testStr.rangeOfString(emailRegEx, options:.RegularExpressionSearch)
    let result = range != nil ? true : false
    return result
}

Remarque: longueur du TLD mise à jour.

Voici le RegEx définitif pour le courrier électronique selon la RFC 5322, notez qu'il est préférable de ne pas l'utiliser car il vérifie uniquement la syntaxe de base des adresses électroniques et ne vérifie pas si le domaine de premier niveau existe.

(?: [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]) +)
     \])

Voir Regular-Expressions.info pour des informations plus complètes sur les RegEx par e-mail.

Notez qu'aucun échappement comme requis par un langage tel que Objective-C ou Swift.

zaph
la source
1
l'emailRegEx que vous utilisez est tout simplement faux. Il n'autorise que les TLD de 2 à 4 caractères, tandis que des domaines similaires .engineerexistent.
Antzi
Compris, je ne défends pas ma réponse mais le niveau de l'édition. Ajoutez un commentaire comme ci-dessus, votez, indiquez une meilleure réponse, ajoutez votre propre réponse. Il n'est pas approprié de modifier substantiellement une réponse. J'ai ajouté le RegEx diffusif pour être complet.
zaph
Pourquoi oh pourquoi ne pas simplement supprimer la réponse alors? Quelle raison pourrait-il y avoir de le garder ici?
Fattie
7

Je préfère utiliser une extension pour cela. En outre, cette URL http://emailregex.com peut vous aider à tester si regex est correct. En fait, le site propose différentes implémentations pour certains langages de programmation. Je partage mon implémentation pour Swift 3 .

extension String {
    func validateEmail() -> Bool {
        let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"
        return NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: self)
    }
}
Marlon Ruiz
la source
il y a quelques problèmes .. vous pouvez avoir, par exemple .. blah @ .abc avec un point bizarre là
Fattie
5

Pour swift 2.1: cela fonctionne correctement avec l'email foo @ bar

extension String {
    func isValidEmail() -> Bool {
        do {
            let regex = try NSRegularExpression(pattern: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}", options: .CaseInsensitive)
            return regex.firstMatchInString(self, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, self.characters.count)) != nil
        } catch {
                return false
        }
    }
}
lee5783
la source
1
Cela semble bien fonctionner pour moi. Autant que je sache, vous pouvez même omettre le 'AZ' (lettres majuscules) car vous avez l'option .CaseInsensitive définie de toute façon ...
AZOM
Notez que la propriété de longueur NSRange doit utiliser String utf16.count au lieu de characters.count
Leo Dabus
5

Utilisation de Swift 4.2

extension String {
    func isValidEmail() -> Bool {
        let regex = try? NSRegularExpression(pattern: "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$", options: .caseInsensitive)
        return regex?.firstMatch(in: self, options: [], range: NSMakeRange(0, self.count)) != nil
    }
    func isValidName() -> Bool{
        let regex = try? NSRegularExpression(pattern: "^[\\p{L}\\.]{2,30}(?: [\\p{L}\\.]{2,30}){0,2}$", options: .caseInsensitive)

        return regex?.firstMatch(in: self, options: [], range: NSMakeRange(0, self.count)) != nil
    } }

Et utilisé

if (textField.text?.isValidEmail())! 
    {
      // bla bla
    }
else 
    {

    }
ikbal
la source
4

Il s'agit d'une nouvelle version de "LA SOLUTION RAISONNABLE" de @Fattie, testée sur Swift 4.1 dans un nouveau fichier appelé String+Email.swift:

import Foundation

extension String {
    private static let __firstpart = "[A-Z0-9a-z]([A-Z0-9a-z._%+-]{0,30}[A-Z0-9a-z])?"
    private static let __serverpart = "([A-Z0-9a-z]([A-Z0-9a-z-]{0,30}[A-Z0-9a-z])?\\.){1,5}"
    private static let __emailRegex = __firstpart + "@" + __serverpart + "[A-Za-z]{2,6}"

    public var isEmail: Bool {
        let predicate = NSPredicate(format: "SELF MATCHES %@", type(of:self).__emailRegex)
        return predicate.evaluate(with: self)
    }
}

Son utilisation est donc simple:

let str = "[email protected]"
if str.isEmail {
    print("\(str) is a valid e-mail address")
} else {
    print("\(str) is not a valid e-mail address")
}

Je n'aime tout simplement pas ajouter un funcaux Stringobjets, car être une adresse e-mail leur est inhérente (ou non). Donc, une Boolpropriété conviendrait mieux qu'un func, d'après ma compréhension.

Alejandro Iván
la source
2

Créez une extension simple:

extension NSRegularExpression {

    convenience init(pattern: String) {
        try! self.init(pattern: pattern, options: [])
    }
}

extension String {

    var isValidEmail: Bool {
        return isMatching(expression: NSRegularExpression(pattern: "^[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$"))
    }

    //MARK: - Private

    private func isMatching(expression: NSRegularExpression) -> Bool {
        return expression.numberOfMatches(in: self, range: NSRange(location: 0, length: characters.count)) > 0
    }
}

Exemple:

"[email protected]".isValidEmail //true
"b@bb".isValidEmail //false

Vous pouvez étendre suivant l' extension à tout ce dont vous avez besoin: isValidPhoneNumber, isValidPasswordetc ...

Bartłomiej Semańczyk
la source
Notez que la NSRangepropriété length doit utiliser à la String utf16.countplace decharacters.count
Leo Dabus
2

Dans Swift 4.2 et Xcode 10.1

//Email validation
func isValidEmail(email: String) -> Bool {
    let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
    var valid = NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: email)
    if valid {
        valid = !email.contains("Invalid email id")
    }
    return valid
}

//Use like this....
let emailTrimmedString = emailTF.text?.trimmingCharacters(in: .whitespaces)
if isValidEmail(email: emailTrimmedString!) == false {
   SharedClass.sharedInstance.alert(view: self, title: "", message: "Please enter valid email")
}

Si vous souhaitez utiliser SharedClass.

//This is SharedClass
import UIKit
class SharedClass: NSObject {

static let sharedInstance = SharedClass()

//Email validation
func isValidEmail(email: String) -> Bool {
    let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
    var valid = NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: email)
    if valid {
        valid = !email.contains("Invalid email id")
    }
    return valid
}

private override init() {

}
}

Et appelez une fonction comme celle-ci ...

if SharedClass.sharedInstance. isValidEmail(email: emailTrimmedString!) == false {
   SharedClass.sharedInstance.alert(view: self, title: "", message: "Please enter correct email")
   //Your code here
} else {
   //Code here
}
iOS
la source
1

J'ai fait une bibliothèque conçue pour les validations d'entrée et l'un des "modules" vous permet de valider facilement un tas de trucs ...

Par exemple pour valider un email:

let emailTrial = Trial.Email
let trial = emailTrial.trial()

if(trial(evidence: "[email protected]")) {
   //email is valid
}

SwiftCop est la bibliothèque ... j'espère que cela vous aidera!

Andres
la source
1

Voici une extension dans Swift 3

extension String {
    func isValidEmail() -> Bool {
        let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
        return NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: self)
    }
}

Utilisez-le simplement comme ceci:

if yourEmailString.isValidEmail() {
    //code for valid email address
} else {
    //code for not valid email address
}
gefilte poisson
la source
Changer pour utiliser la réponse Regex d'Alexcristea, c'est la solution parfaite.
Ittgung
0

Puisqu'il y a tellement de noms de domaine de premier niveau étranges maintenant, j'arrête de vérifier la longueur du domaine de premier plan ...

Voici ce que j'utilise:

extension String {

    func isEmail() -> Bool {
        let emailRegEx = "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$"
        return NSPredicate(format:"SELF MATCHES %@", emailRegEx).evaluateWithObject(self)
    } 
}
bonhommes de neige10
la source
0

Semble fonctionner aussi ...

let regex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"

func validate(email: String) -> Bool {
    let matches = email.rangeOfString(regex, options: .RegularExpressionSearch)
    if let _ = matches {
        return true
    }
    return false
}
Logicopolis
la source
0

Réponse mise à jour @Arsonik à Swift 2.2, en utilisant un code moins détaillé que les autres solutions proposées:

extension String {
    func isValidEmail() -> Bool {
        let regex = try? NSRegularExpression(pattern: "^[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])?)*$", options: .CaseInsensitive)
        return regex?.firstMatchInString(self, options: [], range: NSMakeRange(0, self.characters.count)) != nil
    }
}
Matias Seijas
la source
abcd @ a passe avec cette expression régulière. Vous devriez le réparer.
Gunhan
Notez que la propriété de longueur NSRange doit utiliser String utf16.count au lieu de characters.count
Leo Dabus
0

@ La réponse de JeffersonBe est proche, mais renvoie truesi la chaîne est "quelque chose contenant quelqu'[email protected] un email valide" qui n'est pas ce que nous voulons. Ce qui suit est une extension sur String qui fonctionne bien (et permet de tester pour phoneNumber valide et d'autres détecteurs de données pour démarrer.

/// Helper for various data detector matches.
/// Returns `true` iff the `String` matches the data detector type for the complete string.
func matchesDataDetector(type: NSTextCheckingResult.CheckingType, scheme: String? = nil) -> Bool {
    let dataDetector = try? NSDataDetector(types: type.rawValue)
    guard let firstMatch = dataDetector?.firstMatch(in: self, options: NSRegularExpression.MatchingOptions.reportCompletion, range: NSRange(location: 0, length: length)) else {
        return false
    }
    return firstMatch.range.location != NSNotFound
        // make sure the entire string is an email, not just contains an email
        && firstMatch.range.location == 0
        && firstMatch.range.length == length
        // make sure the link type matches if link scheme
        && (type != .link || scheme == nil || firstMatch.url?.scheme == scheme)
}
/// `true` iff the `String` is an email address in the proper form.
var isEmail: Bool {
    return matchesDataDetector(type: .link, scheme: "mailto")
}
/// `true` iff the `String` is a phone number in the proper form.
var isPhoneNumber: Bool {
    return matchesDataDetector(type: .phoneNumber)
}
/// number of characters in the `String` (required for above).
var length: Int {
    return self.characters.count
}
Gujamin
la source
Notez que la propriété de longueur NSRange doit utiliser String utf16.count au lieu de characters.count
Leo Dabus
0

Et pour Swift 3 :

extension String {
    func isValidEmail() -> Bool {
        let regex = try? NSRegularExpression(pattern: "^[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])?)*$", options: .caseInsensitive)
        return regex?.firstMatch(in: self, options: [], range: NSMakeRange(0, self.characters.count)) != nil
    }
}
Danut Pralea
la source
Notez que la propriété de longueur NSRange doit utiliser String utf16.count au lieu de characters.count
Leo Dabus
0

Mon seul ajout à la liste des réponses serait que pour Linux, NSRegularExpressionn'existe pas, c'est en faitRegularExpression

    func isEmail() -> Bool {

    let patternNormal = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"

    #if os(Linux)
        let regex = try? RegularExpression(pattern: patternNormal, options: .caseInsensitive)
    #else
        let regex = try? NSRegularExpression(pattern: patternNormal, options: .caseInsensitive)
    #endif

    return regex?.firstMatch(in: self, options: [], range: NSMakeRange(0, self.characters.count)) != nil

Cela se compile avec succès sur macOS et Ubuntu.

Andrei Popa
la source
Notez que la propriété de longueur NSRange doit utiliser String utf16.count au lieu de characters.count
Leo Dabus
0

Meilleure solution avec le meilleur résultat pour

Swift 4.x

 extension String {

        func validateAsEmail() -> Bool {
            let emailRegEx = "(?:[a-zA-Z0-9!#$%\\&‘*+/=?\\^_`{|}~-]+(?:\\.[a-zA-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])+)\\])"

            let emailTest = NSPredicate(format:"SELF MATCHES[c] %@", emailRegEx)
            return emailTest.evaluate(with: self)
        }
    }
Abdelahad Darwish
la source
0

J'aime créer une extension

   extension String {

func isValidateEmail() -> Bool {
    let emailFormat = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
    let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailFormat)
    return emailPredicate.evaluate(with: self)
}

}

usage:

if emailid.text!.isValidateEmail() == false(){
 //do what ever you want if string is not matched.

}
siva kumar
la source
0

Swift 5

 func isValidEmailAddress(emailAddressString: String) -> Bool {

 var returnValue = true
 let emailRegEx = "[A-Z0-9a-z.-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,3}"

 do {
        let regex = try NSRegularExpression(pattern: emailRegEx)
        let nsString = emailAddressString as NSString
        let results = regex.matches(in: emailAddressString, range: NSRange(location: 0, length: nsString.length))

        if results.count == 0
        {
            returnValue = false
        }

    } catch let error as NSError {
        print("invalid regex: \(error.localizedDescription)")
        returnValue = false
    }

    return  returnValue
}

Ensuite:

let validEmail = isValidEmailAddress(emailAddressString: "[email protected]")
print(validEmail)
Arafin Russell
la source
0

Regex parfait comme Google Email

"^[A-Z0-9a-z][a-zA-Z0-9_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
ami rt
la source
2
celui qui vote ma réponse, veuillez vérifier vos connaissances. J'ai appliqué ce regex dans de nombreux codes et mes amis utilisent ce regex et cela fonctionne très bien .. Avant de voter ma réponse, veuillez commenter et faites-moi savoir ce qui ne va pas avec ce regex.
ami rt
Je pense que je peux répondre: votre regex est simple et ne correspond pas au RFC. Par exemple, les e-mails peuvent avoir des guillemets et même des espaces dans la première partie! Regardez haacked.com/archive/2007/08/21/…
Hugal31
1
Désolé, mon frère, je pense que vous devriez vérifier la validation des e-mails Google, il n'y a aucun moyen d'ajouter de l'espace dans la première partie d'un e-mail, et si mon expression rationnelle est erronée, alors pourquoi personne ne poste-t-il une écriture et une expression rationnelle parfaite?
ami rt le
Selon le RFC 5322, "Bonjour tout le monde!" @ Example.com est un e-mail valide. En effet, il est presque impossible de faire une regex valide. Tous les fournisseurs de messagerie ne s'en tiennent pas à la validation de la messagerie Google.
Hugal31
1
C'est ce que je veux écouter, et c'est pourquoi j'ai mentionné en gras que ci-dessus l'expression régulière est comme Google. Merci
ami rt le
-1

Ou vous pouvez avoir une extension pour le texte facultatif de UITextField:

comment utiliser:

if  emailTextField.text.isEmailValid() {
      print("email is valid")
}else{
      print("wrong email address")
}

extension:

extension Optional where Wrapped == String {
    func isEmailValid() -> Bool{
        guard let email = self else { return false }
        let emailPattern = "[A-Za-z-0-9.-_]+@[A-Za-z0-9]+\\.[A-Za-z]{2,3}"
        do{
            let regex = try NSRegularExpression(pattern: emailPattern, options: .caseInsensitive)
            let foundPatters = regex.numberOfMatches(in: email, options: .anchored, range: NSRange(location: 0, length: email.count))
            if foundPatters > 0 {
                return true
            }
        }catch{
            //error
        }
        return false
    }
}
Maciej Chrzastek
la source
Notez que la propriété NSRange length doit utiliser String utf16.count au lieu de characters.count
Leo Dabus