Wie kann ich eine E-Mail-Adresse schnell überprüfen?


338

Weiß jemand, wie man eine E-Mail-Adresse in Swift validiert? Ich habe diesen Code gefunden:

- (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;
    }
}

aber ich kann es nicht in Swift übersetzen.


8
Die Übersetzung sollte unkompliziert sein. Welcher Teil gibt Ihnen Probleme?
Sulthan

12
Vergessen Sie nicht zu beten, dass keiner Ihrer Benutzer eine der neuen Top-Level-Domains hat. ZB.coffee
Matthias Bauch

1
@Antzi: Ich habe mit "jemand @ gmail" nachgefragt und Ihre Regex hat true zurückgegeben.
Anông An

2
Regexes funktionieren nicht, um zu überprüfen, ob Benutzer ihre E-Mail-Adresse eingegeben haben. Der einzig 100% korrekte Weg ist das Senden einer Aktivierungs-E-Mail. Siehe: Ich wusste, wie man eine E-Mail-Adresse validiert, bis ich den RFC gelesen habe
mouviciel

2
Dies ist eine faszinierende Qualitätssicherung. Es ist mit ziemlicher Sicherheit die "falscheste" Qualitätssicherung auf der gesamten Website. Die derzeit Nr. 1 Antwort mit 600 Stimmen (was?!) Ist in jeder Hinsicht absolut, völlig falsch (jede einzelne Zeile ist völlig falsch und jedes Konzept und jede Idee ist falsch ........ !!!) Viele der anderen hoch bewerteten Antworten sind entweder "völlig falsch", "extrem schäbig" oder einfach kaputt und werden nicht einmal kompiliert. Während die Natur dieses Q "Elite-Regex-Engineering" erfordert, bieten viele Antworten (hoch gewählt!) Entsetzliches Regex-Engineering. Es ist eine wirklich interessante Qualitätssicherung !! Warum??
Fattie

Antworten:


769

Ich würde verwenden 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)
}

für Versionen von Swift vor 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)
}

für Versionen von Swift vor 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
}

6
wäre nicht return emailTest.evaluateWithObject(testStr)viel einfacher und lesbarer? Im Vergleich zu == trueist ein bisschen wie Javascript.
Sulthan

15
Es wird nicht
geprüft

6
Dies gilt nicht für test @ test ... com
Alan

3
Dies erkennt keine E-Mails. @ Invalid.com oder E-Mails @ .invalid.com. Die Antwort unten von @alexcristea tut
Ben Sullivan

3
Es ist ziemlich lustig, dass ............ sowie (1) der Regex völlig falsch ist (2) der Regex (selbst im Kontext dessen, was er zu tun versucht) schwerwiegende Fehler aufweist ( 3) die Swift ist falsch (4) auch das beiseite Einstellung der Stil völlig falsch ist (5) nicht , dass es den ganzen Rest gegeben Angelegenheiten , aber es nicht einmal erwähnen , dass Sie haben cachen das Prädikat ... humoristisch, ( 6) Es ist noch Code übrig ("Kalender" - was?), Von wo auch immer er kopiert wurde.
Fattie

115

Bearbeitung, aktualisiert für 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)

}

Ursprüngliche Antwort für 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)

}

Es funktioniert gut.


2
der erste mit einem gültigen regulären Ausdruck. die anderen validieren aa @ aach zu true
netshark1000

1
@ netshark1000, nur mit Upvotes, jede Antwort wird oben sein. :)
Azik Abdullah

NSRegularExpression ist einfacher zu verwenden als NSPredicate
Guillaume Laurent

1
Die Bedingung mit zwei Punkten nach dem Domänennamen wird nicht behandelt. Versuchen Sie diese Antwort stackoverflow.com/a/53441176/5032981
Prashant Gaikwad

@ AzikAbdullah Wenn Sie 'abc @ gmail..com' eingeben, wird es auch validiert
Nij

110

Als StringKlassenerweiterung

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
    }
}

Verwendungszweck

if "rdfsdsfsdfsd".isValidEmail() {

}

4
countElementsist jetztcount
Zack Shapiro

25
xxx @ yyy return true?
Cullen SUN

1
Wie bei Cullen SUN gibt foo @ bar true zurück.
Rémy Virin

3
user @ host ohne .tld ist auch eine gültige E-Mail-Adresse, zB root @ localhost
Mi

1
Beachten Sie, dass die NSRange-Längeneigenschaft den String utf16.count anstelle der Zeichen verwenden sollte. Count
Leo Dabus

64

Wenn Sie nach einer sauberen und einfachen Lösung suchen, sollten Sie sich https://github.com/nsagora/validation-components ansehen .

Es enthält ein E-Mail-Validierungsprädikat, das sich leicht in Ihren Code integrieren lässt:

let email = "test@example.com"
let rule = EmailValidationPredicate()
let isValidEmail = rule.evaluate(with: email)

Hinter der Haube wird der RFC 5322 reg ex ( http://emailregex.com ) verwendet:

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])+)\\])"

3
Wow, wusste nichts über emailregex.com. Es ist großartig!
Samuel Ev

2
Schließlich eine, die E-Mails filtert. @. Email.com
Ben Sullivan

es funktioniert mit genau - abcd@abcd.com. es ist nicht validieren abc @ abc
Anil Gupta

Ah, endlich ..: D
Ümañg ßürmån

39

Hier ist die vernünftige Lösung:

"DIE ANGEMESSENE LÖSUNG"

Wird seit Jahren in vielen großvolumigen Apps verwendet und getestet.

1 - es vermeidet die vielen schrecklichen Regex-Fehler, die Sie oft in diesen Vorschlägen sehen

2 - Es erlaubt KEINE dummen E-Mails wie "x @ x", die unter bestimmten RFCs als gültig gelten, aber völlig albern sind, nicht als E-Mails verwendet werden können und die Ihre Support-Mitarbeiter sofort ablehnen würden und die alle Mailer-Dienste (Mailchimp, Google, Aws usw.) lehnen einfach ab. Wenn Sie (aus irgendeinem Grund) eine Lösung benötigen, die Zeichenfolgen wie 'x @ x' zulässt, verwenden Sie eine andere Lösung.

3 - Der Code ist sehr, sehr, sehr verständlich

4 - es ist KISS, zuverlässig und auf kommerziellen Apps mit einer enormen Anzahl von Benutzern bis zur Zerstörung getestet

5 - ein technischer Punkt, das Prädikat ist ein globales, wie Apple es vorschreibt (achten Sie auf Code-Vorschläge, die dies nicht haben)

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()
    }
}

So einfach ist das.

Erläuterung:

In der folgenden Beschreibung bedeutet "OC" ein gewöhnliches Zeichen - ein Buchstabe oder eine Ziffer.

__firstpart ... muss mit einem OK beginnen und enden . Für die Zeichen in der Mitte können Sie bestimmte Zeichen wie Unterstrich verwenden, aber Anfang und Ende müssen ein OK sein. (Allerdings ist es in Ordnung , nur ein OC zu haben , und das ist es, zum Beispiel: j@blah.com)

__serverpart ... Sie haben Abschnitte wie " bla ". welche wiederholen . (Also mail.city.fcu.edu Art der Sache.) Die Abschnitte müssen mit einem OC beginnen und enden , aber in der Mitte können Sie auch einen Bindestrich "-" haben. (Wenn Sie andere ungewöhnliche Zeichen zulassen möchten , z. B. den Unterstrich, fügen Sie einfach vor dem Bindestrich hinzu.) Es ist in Ordnung , einen Abschnitt zu haben, der nur ein OK ist. (Wie in joe@w.campus.edu) Sie können bis zu fünf Abschnitte haben, Sie müssen einen haben. Schließlich ist die TLD (wie z. B. .com) streng 2 bis 8 groß. Ändern Sie einfach diese "8", wie von Ihrer Support-Abteilung bevorzugt.


WICHTIG!

Sie müssen das Prädikat als global beibehalten und nicht jedes Mal erstellen.

Beachten Sie, dass dies das erste ist, was Apple in den Dokumenten über das gesamte Problem erwähnt .

Es ist sehr überraschend, wenn Sie Vorschläge sehen, die das Prädikat nicht zwischenspeichern.


1
Unterstützt es neue TLDs wie .engineer?
Roman

hi @Roman - beachte, wo deutlich steht "Schließlich besteht die TLD (.com oder ähnliches) ausschließlich aus 2 bis 8 Buchstaben." Das kümmert sich darum. Sie können die "8" auf einen von Ihnen bevorzugten Wert ändern. (Im Moment lehnt der Kundenservice in vielen großen Unternehmen lange TLDs einfach als Betrug ab - aber es ist trotzdem Ihre Entscheidung, "8" oder einen beliebigen Wert zu verwenden.)
Fattie

2
Zu Punkt (4): Wie haben Sie mit vielen Benutzern getestet? Haben Sie die Benutzer verfolgt, die sich nicht bei den kommerziellen Apps anmelden konnten, weil der reguläre Ausdruck sie daran gehindert hat, ihre E-Mail-Adresse zu verwenden? Das einzig "Vernünftige" sollte sein, was die Spezifikation (RFC) spezifiziert oder wenn dies nicht erreicht werden kann, dann etwas, das entspannter ist, aber alles von der Spezifikation abdeckt. Wenn die Benutzer x @ x nicht eingeben dürfen, geben sie garbage@example.com ein, das Ihren / jeden regulären Ausdruck weitergibt.
Thetrutz

hi @thetrutz, "garbage@example.com" ist eine ganz normale E-Mail-Adresse. Der RFC enthält theoretische Idiotie wie "x @ x". Jeder tatsächliche gewerbliche Kunde, für den Sie oder ich jemals arbeiten, sagt "diese nicht zulassen". (Beachten Sie, dass es in jedem realen Großunternehmen weitaus mehr Einschränkungen gibt als meine grobe Darstellung hier, wie ich im obigen Kommentar zu Roman erwähne.) Ihr letzter Satz ist verwirrend - natürlich wird eine "nicht funktionierende E-Mail" eine passieren lokaler Test? Was meinst du? Offensichtlich werden E-Mails letztendlich nur über Systeme zum Bestätigen Ihrer E-Mails überprüft.
Fattie

In Swift muss jeder Prozess optimiert werden, da wir diese Sprache normalerweise auf der Serverseite verwenden.
Nicolas Manzini

25

Hier ist eine Sicherung der beiden am häufigsten bewerteten Antworten mit dem richtigen regulären Ausdruck: eine String-Erweiterung mit Prädikat, damit Sie string.isEmail aufrufen können

    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)
        }
    }

19

Einfachster Weg in 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)
    }
}

Beispiel

"kenmueller0@gmail.com".isValidEmail

kehrt zurück...

true

2
Was bringt es, die wiederholte Antwort zu wiederholen? Das hängt nicht von Swift 5-Funktionen ab
Rommex

17

Ich würde vorschlagen, es als Erweiterung von String zu verwenden:

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
    }
}

Und um es zu benutzen:

if "hodor@gameofthrones.com".isEmail { // true
    print("Hold the Door")
}

1
Beachten Sie, dass die NSRange-Längeneigenschaft den String utf16.count anstelle der Zeichen verwenden sollte. Count
Leo Dabus

Update Swift 4: Erweiterung String {public var isEmail: Bool {let dataDetector = try? NSDataDetector (Typen: NSTextCheckingResult.CheckingType.link.rawValue) let firstMatch = dataDetector? .FirstMatch (in: self, Optionen: NSRegularExpression.MatchingOptions.reportCompletion, Bereich: NSRange (Speicherort: 0, Länge: Anzahl)) return (firstMatch?. range.location! = NSNotFound && firstMatch? .url? .scheme == "mailto")}
Duan Nguyen

15

Dies ist die aktualisierte Version für 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
    }
}

8
foo @ bar gibt true zurück ?!
Rémy Virin

2
validiert aa @ aach auf true
netshark1000

4
Das liegt daran, dass der RFC diese E-Mail-Adressen auf true überprüft;)
Dulgan

Beachten Sie, dass die NSRange-Längeneigenschaft den String utf16.count anstelle der Zeichen verwenden sollte. Count
Leo Dabus

Es ist wirklich falsch / schlecht, das Prädikat nicht zwischenzuspeichern. Es ist das erste, was Apple über das Problem im Dokument sagt. Ein eklatanter Fehler, den die meisten Antworten auf der Seite gemacht haben.
Fattie

9

Hier gibt es viele richtige Antworten, aber viele der "regulären Ausdrücke" sind unvollständig und es kann vorkommen, dass eine E-Mail wie "name @ domain" eine gültige E-Mail ergibt, dies ist jedoch nicht der Fall. Hier die Komplettlösung:

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
        }
    }
}

funktioniert nicht richtig, Sie können Leerzeichen nach der Domäne hinzufügen.
Juan Boero

Beachten Sie, dass die NSRange-Längeneigenschaft den String utf16.count anstelle der Zeichen verwenden sollte. Count
Leo Dabus

@ Fattie argumentieren Ihre Aussage. Ihr Kommentar ist sehr nutzlos, schlagen Sie eine Verbesserung vor, schlagen Sie eine Lösung vor. Völlig falsch zu sagen ist sehr dumm und liegt einer engen Mentalität zugrunde
Andrea.Ferrando

"Hier gibt es viele richtige Antworten" dieser Satz ist spektakulär falsch :) :)
Fattie

8

Hier ist eine Methode basierend auf 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
}

Hinweis: Aktualisierte TLD-Länge.

Hier ist das endgültige RegEx für E-Mails gemäß RFC 5322. Beachten Sie, dass dies am besten nicht verwendet wird, da nur die grundlegende Syntax von E-Mail-Adressen überprüft wird und nicht überprüft wird, ob die Domäne der obersten Ebene vorhanden ist.

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

Siehe Regular-Expressions.info für vollständigere Informationen über E - Mail regexs.

Beachten Sie, dass eine Sprache wie Objective-C oder Swift kein Entkommen erfordert.


1
Das von Ihnen verwendete emailRegEx ist einfach falsch. TLDs mit einer Länge von 2 bis 4 Zeichen sind nur zulässig, während Domänen wie .engineervorhanden vorhanden sind.
Antzi

Verstanden verteidige ich nicht meine Antwort, sondern die Ebene der Bearbeitung. Fügen Sie einen Kommentar wie oben hinzu, stimmen Sie ab, zeigen Sie auf eine bessere Antwort, fügen Sie Ihre eigene Antwort hinzu. Es ist nicht angebracht, eine Antwort wesentlich zu ändern. Der Vollständigkeit halber habe ich das diffusive RegEx hinzugefügt.
Zaph

Warum, warum nicht einfach die Antwort löschen? Welchen möglichen Grund könnte es geben, es hier zu behalten?
Fattie

7

Ich bevorzuge dafür eine Erweiterung. Außerdem kann diese URL http://emailregex.com Ihnen helfen, zu testen, ob Regex korrekt ist. Tatsächlich bietet die Site verschiedene Implementierungen für einige Programmiersprachen. Ich teile meine Implementierung für 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)
    }
}

Es gibt ein paar Probleme .. Sie können zum Beispiel .. blah @ .abc mit einem seltsamen Punkt dort haben
Fattie

5

Für Swift 2.1: Dies funktioniert korrekt mit E-Mail 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
        }
    }
}

1
Das scheint für mich gut zu funktionieren. Soweit ich weiß, können Sie sogar die 'AZ' (Großbuchstaben) weglassen, da Sie die Option .CaseInsensitive sowieso eingestellt haben ...
AZOM

Beachten Sie, dass die NSRange-Längeneigenschaft den String utf16.count anstelle der Zeichen verwenden sollte. Count
Leo Dabus

5

Verwendung von 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
    } }

Und gebraucht

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

    }

4

Dies ist eine neue Version für "THE REASONABLE SOLUTION" von @Fattie, getestet auf Swift 4.1 in einer neuen Datei namens 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)
    }
}

Die Verwendung ist also einfach:

let str = "mail@domain.com"
if str.isEmail {
    print("\(str) is a valid e-mail address")
} else {
    print("\(str) is not a valid e-mail address")
}

Ich mag es einfach nicht func, den StringObjekten ein hinzuzufügen , da ihnen eine E-Mail-Adresse inhärent ist (oder nicht). Nach meinem Verständnis Boolwürde eine Immobilie also besser passen als eine func.


2

Erstellen Sie eine einfache Erweiterung:

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
    }
}

Beispiel:

"b@bb.pl".isValidEmail //true
"b@bb".isValidEmail //false

Sie können folgende Erweiterung etwas erweitern Sie brauchen: isValidPhoneNumber, isValidPasswordetc ...


Beachten Sie, dass NSRangeLänge Eigenschaft String utf16.countanstelle voncharacters.count
Leo Dabus

Das Muster ist völlig falsch
Fattie

2

In Swift 4.2 und 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")
}

Wenn Sie SharedClass verwenden möchten.

//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() {

}
}

Und Funktion wie diese aufrufen ....

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

1

Ich habe eine Bibliothek für Eingabevalidierungen erstellt und eines der "Module" ermöglicht es Ihnen, eine Reihe von Dingen einfach zu validieren ...

Zum Validieren einer E-Mail:

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

if(trial(evidence: "test@test.com")) {
   //email is valid
}

SwiftCop ist die Bibliothek ... hoffe es hilft!


1

Hier ist eine Erweiterung in 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)
    }
}

Verwenden Sie es einfach so:

if yourEmailString.isValidEmail() {
    //code for valid email address
} else {
    //code for not valid email address
}

Wenn Sie den Regex aus der Antwort von alexcristea verwenden, ist dies die perfekte Lösung.
Ittgung

0

Da es jetzt so viele seltsame Top-Level-Domain-Namen gibt, höre ich auf, die Länge der Top-Domain zu überprüfen ...

Folgendes benutze ich:

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)
    } 
}

0

Scheint auch zu funktionieren ...

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
}

0

Aktualisierte Antwort @Arsonik Antwort auf Swift 2.2 mit weniger ausführlichem Code als andere angebotene Lösungen:

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
    }
}

abcd @ a wird mit diesem regulären Ausdruck übergeben. Sie sollten es beheben.
Gunhan

Beachten Sie, dass die NSRange-Längeneigenschaft den String utf16.count anstelle der Zeichen verwenden sollte. Count
Leo Dabus

0

Die Antwort von @ JeffersonBe ist knapp, wird aber zurückgegeben, truewenn die Zeichenfolge "etwas enthält, das jemand@something.com eine gültige E-Mail enthält", was nicht das ist, was wir wollen. Das Folgende ist eine Erweiterung von String, die gut funktioniert (und das Testen auf gültige phoneNumber und andere Datendetektoren zum Booten ermöglicht.

/// 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
}

Beachten Sie, dass die NSRange-Längeneigenschaft den String utf16.count anstelle der Zeichen verwenden sollte. Count
Leo Dabus

0

Und für 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
    }
}

Beachten Sie, dass die NSRange-Längeneigenschaft den String utf16.count anstelle der Zeichen verwenden sollte. Count
Leo Dabus

0

Mein einziger Zusatz zur Liste der Antworten wäre, dass es für Linux NSRegularExpressionnicht existiert, es ist tatsächlichRegularExpression

    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

Dies wird sowohl unter MacOS als auch unter Ubuntu erfolgreich kompiliert.


Beachten Sie, dass die NSRange-Längeneigenschaft den String utf16.count anstelle der Zeichen verwenden sollte. Count
Leo Dabus

0

Beste Lösung mit bestem Ergebnis für

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)
        }
    }

0

Ich mag es, eine Erweiterung zu erstellen

   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)
}

}

Verwendungszweck:

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

}

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
}

Dann:

let validEmail = isValidEmailAddress(emailAddressString: "your@email.com")
print(validEmail)

0

Perfekter Regex wie Google Email

"^[A-Z0-9a-z][a-zA-Z0-9_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"

2
Wer auch immer meine Antwort abstimmt, bitte überprüfen Sie Ihr Wissen. Ich habe diesen regulären Ausdruck in vielen Codes angewendet und meine Freunde verwenden diesen regulären Ausdruck und er funktioniert hervorragend. Bevor Sie meine Antwort abwählen, kommentieren Sie bitte und lassen Sie mich wissen, was mit diesem regulären Ausdruck nicht stimmt.
Ami rt

Ich denke, ich kann antworten: Ihr regulärer Ausdruck ist zu einfach und stimmt nicht mit dem RFC überein. Zum Beispiel können E-Mails im ersten Teil Anführungszeichen und sogar Leerzeichen enthalten! Schauen Sie sich haacked.com/archive/2007/08/21/…
Hugal31

1
Tut mir leid, Bruder, ich denke, Sie sollten die Google-E-Mail-Validierung überprüfen. Es gibt keine Möglichkeit, im ersten Teil einer E-Mail Leerzeichen hinzuzufügen. Wenn meine Regex falsch ist, warum schreibt dann niemand einen Schreib- und perfekten Regex?
Ami rt

Laut RFC 5322 ist "Hallo Welt!" @ Example.com eine gültige E-Mail. In der Tat ist es fast unmöglich, einen gültigen regulären Ausdruck zu erstellen. Nicht jeder E-Mail-Anbieter wird sich an die Google E-Mail-Validierung halten.
Hugal31

1
Das ist es, was ich hören möchte, und deshalb habe ich in Fettdruck erwähnt, dass über Regex wie Google ist. Vielen Dank
ami rt

-1

Oder Sie können eine Erweiterung für den optionalen Text von UITextField haben:

wie benutzt man:

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

Erweiterung:

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
    }
}

Beachten Sie, dass die NSRange-Längeneigenschaft den String utf16.count anstelle der Zeichen verwenden sollte. Count
Leo Dabus
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.