Jak szybko zweryfikować adres e-mail?


338

Czy ktoś wie, jak zweryfikować adres e-mail w Swift? Znalazłem ten kod:

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

ale nie mogę go przetłumaczyć na Swift.


8
tłumaczenie powinno być proste. Jaka część sprawia ci problemy?
Sulthan

12
Nie zapomnijcie modlić się, aby żaden z użytkowników nie miał jednej z nowych domen najwyższego poziomu. Np..coffee
Matthias Bauch

1
@Antzi: Sprawdziłem za pomocą „ktoś @ gmail” i twoje wyrażenie regularne zwróciło wartość „prawda”.
Anông An

2
Regeksy nie sprawdzają, czy użytkownicy wpisali swój adres e-mail. Jedynym w 100% poprawnym sposobem jest wysłanie e-maila aktywacyjnego. Zobacz: Wiedziałem, jak zweryfikować adres e-mail, dopóki nie przeczytam RFC
mouviciel

2
To fascynująca kontrola jakości. Prawie na pewno jest to „najbardziej błędna” kontrola jakości w całej witrynie. Obecnie nr 1 odpowiedź z 600 głosami (co ?!) jest całkowicie, całkowicie błędna pod każdym możliwym względem (każda linia jest całkowicie błędna, a każda koncepcja i idea jest zła ........ !!!) Wiele innych wysoko głosowanych odpowiedzi jest albo „całkowicie błędnych”, „wyjątkowo nieśmiałych”, albo po prostu złamanych i nawet nie kompiluje się. Ponadto, podczas gdy natura tego Q wymaga „elitarnej inżynierii wyrażeń regularnych”, wiele odpowiedzi (wysoko głosowanych!) Zawiera przerażającą inżynierię wyrażeń regularnych. To naprawdę ciekawa kontrola jakości !! Dlaczego??
Fattie

Odpowiedzi:


769

Użyłbym 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)
}

dla wersji Swift wcześniejszych niż 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)
}

dla wersji Swift wcześniejszych niż 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
nie return emailTest.evaluateWithObject(testStr)byłoby o wiele prostsze i czytelniejsze? Porównywanie == truejest trochę jak Javascript.
Sulthan

15
Nie sprawdza, czy jest dostępne rozszerzenie, a @ a jest już OK :(
CularBytes

6
nie dotyczy to testu @ test ... com
Alan

3
Nie wykrywa to adresu e-mail. @ Invalid.com ani adresu e-mail @ .invalid.com. Odpowiedź poniżej z @alexcristea brzmi
Ben Sullivan,

3
To zabawne, że ............ oraz (1) wyrażenie regularne jest całkowicie, całkowicie niepoprawne (2) wyrażenie regularne (nawet w kontekście tego, co próbuje zrobić) zawiera poważne błędy ( 3) Szybki jest w błędzie (4), nawet odkładając na bok, styl jest całkowicie zły (5), nie to, że ma znaczenie, biorąc pod uwagę całą resztę, ale nawet nie wspomina, że ​​musisz buforować orzeczenie ... humorystycznie, ( 6) kod pozostał („kalendarz” - co?) Z dowolnego miejsca, z którego został skopiowany.
Fattie

115

Edycja, zaktualizowana do 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)

}

Oryginalna odpowiedź dla 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)

}

Działa dobrze.


2
pierwszy z poprawnym wyrażeniem regularnym. inni potwierdzają aa @ aach jako true
netshark1000

1
@ netshark1000, tylko z upvotes, każda odpowiedź będzie na górze. :)
Azik Abdullah

NSRegularExpression jest prostszy w użyciu niż NSPredicate
Guillaume Laurent

1
Nie obsługuje warunku dwóch kropek po nazwie domeny. spróbuj tej odpowiedzi stackoverflow.com/a/53441176/5032981
Prashant Gaikwad

@AzikAbdullah Jeśli wpiszesz „abc @ gmail..com”, to również zostanie zatwierdzone
Nij

110

Jako Stringrozszerzenie klasy

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

Stosowanie

if "rdfsdsfsdfsd".isValidEmail() {

}

4
countElementsjest terazcount
Zack Shapiro

25
xxx @ yyy zwrócić prawdę?
Cullen SUN

1
Podobnie jak Cullen SUN, foo @ bar return true.
Rémy Virin

3
użytkownik @ host bez .tld jest również prawidłowym adresem e-mail, np. root @ localhost
śr.

1
Zauważ, że właściwość długości NSRange powinna używać String utf16.count zamiast znaków.count
Leo Dabus

64

Jeśli szukasz czystego i prostego rozwiązania, powinieneś zajrzeć na https://github.com/nsagora/validation-components .

Zawiera predykat sprawdzania poprawności wiadomości e-mail, który można łatwo zintegrować z kodem:

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

Za maską wykorzystuje 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])+)\\])"

3
Wow, nie wiedziałem o emailregex.com. To jest wspaniałe!
Samuel Ev

2
Wreszcie filtr, który filtruje wiadomości e-mail. @. Email.com
Ben Sullivan,

działa z dokładnym - abcd@abcd.com. to nie jest poprawne abc @ abc
Anil Gupta

Ach, w końcu ..: D
Ümañg ßürmån

39

Oto rozsądne rozwiązanie:

„ROZSĄDNE ROZWIĄZANIE”

Używany i testowany od lat w wielu aplikacjach o dużej objętości.

1 - pozwala uniknąć wielu strasznych błędów wyrażenia regularnego, które często widujesz w tych sugestiach

2 - NIE zezwala na głupie wiadomości e-mail, takie jak „x @ x”, które są uważane za prawidłowe w niektórych RFC, ale są całkowicie głupie, nie mogą być używane jako wiadomości e-mail, a które pracownicy wsparcia natychmiast odrzucą, i które wszystkie usługi pocztowe (mailchimp, google, aws itp.) po prostu odrzucają. Jeśli (z jakiegoś powodu) potrzebujesz rozwiązania, które pozwala na takie ciągi znaków jak „x @ x”, użyj innego rozwiązania.

3 - kod jest bardzo, bardzo, bardzo zrozumiały

4 - jest KISS, niezawodny i przetestowany do zniszczenia w aplikacjach komercyjnych z ogromną liczbą użytkowników

5 - kwestia techniczna, predykat jest globalny, jak twierdzi Apple , powinien (uważaj na sugestie kodu, które tego nie mają)

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

To takie proste.

Wyjaśnienie:

W poniższym opisie „OC” oznacza zwykły znak - literę lub cyfrę.

__firstpart ... musi zaczynać się i kończyć OC. Dla znaków pośrodku możesz mieć pewne znaki, takie jak podkreślnik, ale początek i koniec muszą być OC. (Jednakże, jest to ok mieć tylko jedno OC i to, na przykład: j@blah.com)

__serverpart ... Masz sekcje takie jak „bla”. które powtarzają się . (A więc mail.city.fcu.edu.) Sekcje muszą zaczynać się i kończyć OC, ale w środku możesz też wstawić myślnik „-”. (Jeśli chcesz, aby inne nietypowe znaki tam, być może podkreślenia, wystarczy dodać przed myślnikiem). Jest OK , aby mieć sekcję, która jest tylko jeden OC. (Jak w joe@w.campus.edu) Można mieć maksymalnie pięć części, to trzeba mieć. Wreszcie TLD (takie jak .pl) jest ściśle 2 do 8 rozmiaru. Oczywiście po prostu zmień „8” na preferowaną przez dział wsparcia.


WAŻNE!

Musisz zachować predykat jako globalny, nie buduj go za każdym razem.

Zauważ, że jest to pierwsza rzecz, którą Apple wspomina o całym problemie w dokumentacji.

To bardzo zaskakujące, gdy zobaczysz sugestie, które nie buforują predykatu.


1
Czy obsługuje nowe TLD, takie jak .engineer?
Roman

cześć @Roman - zauważ, że wyraźnie mówi „Wreszcie TLD (.com lub podobne) ma od 2 do 8 liter”. To załatwia sprawę. Możesz zmienić „8” na preferowaną wartość. (Na razie w wielu dużych firmach obsługa klienta po prostu odrzuci długie TLD jako oszustwo - ale w każdym razie to twoja decyzja, użyj „8” lub dowolnej wartości, którą lubisz.)
Fattie

2
W odniesieniu do punktu (4): w jaki sposób testowałeś z wieloma użytkownikami? Czy śledziłeś użytkowników, którzy nie mogli zarejestrować się w aplikacjach komercyjnych, ponieważ regex uniemożliwił im użycie ich adresu e-mail? Jedynym „rozsądnym” powinno być to, co określa specyfikacja (RFC) lub jeśli nie można tego osiągnąć, to coś, co jest bardziej zrelaksowane, ale obejmuje wszystko od specyfikacji. Jeśli użytkownicy nie mogą wpisać x @ x, wprowadzą garbage@example.com, który przekaże twoje / dowolne wyrażenie regularne.
thetrutz

cześć @ thetrutz, „garbage@example.com” jest całkowicie normalnym adresem e-mail. RFC obejmuje teoretyczne idiotyzm taki jak „x @ x”. każdy faktyczny klient komercyjny, dla którego ty lub ja kiedykolwiek pracujesz, powie „zabraniać”. (zauważ, że w każdym dużym biznesie w świecie rzeczywistym jest znacznie więcej ograniczeń niż mój ogólny zarys, jak wspomniałem w komentarzu powyżej do Romana). Twoje ostatnie zdanie jest mylące - oczywiście „niedziałający e-mail” przejdzie test lokalny? Co masz na myśli? Oczywiście e-maile są ostatecznie weryfikowane tylko przez systemy „potwierdź swój e-mail”.
Fattie

W Swift istnieje potrzeba optymalizacji każdego procesu, ponieważ zwykle używamy tego języka po stronie serwera.
Nicolas Manzini,

25

Oto połączenie dwóch najczęściej głosowanych odpowiedzi z poprawnym wyrażeniem regularnym: rozszerzenie String przy użyciu predykatu, dzięki czemu można wywołać 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)
        }
    }

19

Najprostszy sposób w 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)
    }
}

Przykład

"kenmueller0@gmail.com".isValidEmail

zwroty...

true

2
jaki jest sens powtarzania powtarzanej odpowiedzi? co nie zależy od żadnych funkcji Swift 5
rommex

17

Sugerowałbym użycie go jako rozszerzenia 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
    }
}

I aby go użyć:

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

1
Zauważ, że właściwość długości NSRange powinna używać String utf16.count zamiast znaków.count
Leo Dabus

Zaktualizuj Swift 4: rozszerzenie Ciąg {public var isEmail: Bool {let dataDetector = spróbuj? NSDataDetector (typy: NSTextCheckingResult.CheckingType.link.rawValue) pozwól firstMatch = dataDetector? .FirstMatch (w: self, opcje: NSRegularExpression.MatchingOptions.reportCompletion, zakres: NSRange (lokalizacja: 0, długość: liczba)) return (firstMatch) range.location! = NSNotFound && firstMatch? .url? .scheme == "mailto")}
Duan Nguyen

15

To jest zaktualizowana wersja dla 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 zwraca wartość prawda?
Rémy Virin

2
sprawdza poprawność aa @ aach na true
netshark1000

4
To dlatego, że RFC sprawdza te adresy e-mail jako prawdziwe;)
dulgan

Zauważ, że właściwość długości NSRange powinna używać String utf16.count zamiast znaków.count
Leo Dabus

naprawdę źle / źle jest nie buforować predykatu. to pierwsza rzecz, jaką Apple mówi o problemie w doco. rażący błąd popełniony przez większość odpowiedzi na stronie.
Fattie

9

Istnieje wiele poprawnych odpowiedzi, ale wiele wyrażeń regularnych jest niekompletnych i może się zdarzyć, że e-mail typu: „nazwa @ domena” będzie zawierał prawidłowy adres e-mail, ale tak nie jest. Oto kompletne rozwiązanie:

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

nie działa poprawnie, pozwala dodawać spacje po domenie.
Juan Boero,

Zauważ, że właściwość długości NSRange powinna używać String utf16.count zamiast znaków.count
Leo Dabus

@Fattie argumentować swoje oświadczenie. Twój komentarz jest bardzo bezużyteczny, sugeruj ulepszenie, zaproponuj poprawkę. Mówienie całkowicie źle jest bardzo głupie i leży u podstaw bliskiej mentalności
Andrea.Ferrando

„Jest tu wiele prawidłowych odpowiedzi” to zdanie jest spektakularnie niepoprawne :) :)
Fattie

8

Oto metoda oparta na 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
}

Uwaga: zaktualizowana długość TLD.

Oto ostateczny RegEx dla poczty e-mail zgodnie z RFC 5322, należy pamiętać, że najlepiej tego nie używać, ponieważ sprawdza on tylko podstawową składnię adresów e-mail i nie sprawdza, czy istnieje domena najwyższego poziomu.

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

Zobacz Regular-Expressions.info, aby uzyskać pełniejsze informacje na temat RegExs e-mailem.

Zauważ, że nie ma zmiany znaczenia zgodnie z wymaganiami języka takiego jak Objective-C lub Swift.


1
używany emailRegEx jest po prostu zły. Dopuszcza tylko domeny TLD o długości od 2 do 4 znaków, podczas gdy takie domeny .engineeristnieją.
Antzi

Rozumiem, że nie bronię swojej odpowiedzi, ale poziom edycji. Dodaj komentarz jak wyżej, głosuj w dół, wskaż lepszą odpowiedź, dodaj własną odpowiedź. Nie należy zasadniczo zmieniać odpowiedzi. Dodałem dyfuzyjny RegEx dla kompletności.
zaph

Dlaczego więc dlaczego nie usunąć odpowiedzi? Jaki może być powód, aby go tu zatrzymać?
Fattie

7

Wolę użyć do tego rozszerzenia. Poza tym ten adres URL http://emailregex.com może pomóc w sprawdzeniu, czy wyrażenie regularne jest poprawne. W rzeczywistości strona oferuje różne implementacje dla niektórych języków programowania. Udostępniam moją implementację dla 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)
    }
}

jest kilka problemów .. możesz mieć na przykład .. bla @ .abc z dziwną kropką
Fattie

5

Dla wersji Swift 2.1: działa to poprawnie z e-mailem 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
Wydaje mi się, że to działa dobrze. O ile rozumiem, można nawet pominąć „AZ” (wielkie litery), ponieważ masz opcję .CaseInsensitive i tak zestaw ...
AZOM

Zauważ, że właściwość długości NSRange powinna używać String utf16.count zamiast znaków.count
Leo Dabus

5

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

I używane

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

    }

4

To nowa wersja REASONABLE SOLUTION” autorstwa @Fattie, przetestowana na Swift 4.1 w nowym pliku o nazwie 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)
    }
}

Jego użycie jest proste:

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

Po prostu nie lubię dodawać funcdo Stringobiektów a, ponieważ adres e-mail jest z nimi związany (lub nie). Tak więc Boolwłasność pasowałaby lepiej niż func, z mojego zrozumienia.


2

Utwórz proste rozszerzenie:

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

Przykład:

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

Można rozszerzyć po rozszerzeniu do niczego potrzebne są: isValidPhoneNumber, isValidPasswordetc ...


Zauważ, że zamiast NSRangedługości należy użyć właściwości lengthString utf16.countcharacters.count
Leo Dabus

2

W Swift 4.2 i 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")
}

Jeśli chcesz użyć 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() {

}
}

I funkcja wywołania taka jak ta ....

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

Stworzyłem bibliotekę przeznaczoną do sprawdzania poprawności danych wejściowych, a jeden z „modułów” pozwala łatwo zweryfikować wiele rzeczy ...

Na przykład, aby sprawdzić poprawność wiadomości e-mail:

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

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

SwiftCop to biblioteka ... mam nadzieję, że pomoże!


1

Oto rozszerzenie do 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)
    }
}

Po prostu użyj tego w ten sposób:

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

Zmieniając użycie Regexu z odpowiedzi Alexandra, jest to idealne rozwiązanie.
ittgung

0

Ponieważ jest teraz tak wiele dziwnych nazw domen najwyższego poziomu, przestaję sprawdzać długość domeny najwyższego poziomu ...

Oto czego używam:

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

Wydaje się też działać ...

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

Zaktualizowano odpowiedź @Arsonik do Swift 2.2, używając mniej pełnego kodu niż inne oferowane rozwiązania:

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 przechodzi z tym wyrażeniem regularnym. Powinieneś to naprawić.
Gunhan

Zauważ, że właściwość długości NSRange powinna używać String utf16.count zamiast znaków.count
Leo Dabus

0

@ Odpowiedź JeffersonBe jest bliska, ale zwraca, truejeśli ciąg znaków to „coś, co zawiera komuś@something.com prawidłowy adres e-mail”, czego nie chcemy. Poniżej znajduje się rozszerzenie String, które działa dobrze (i umożliwia testowanie prawidłowego numeru telefonu i innych detektorów danych do uruchomienia.

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

Zauważ, że właściwość długości NSRange powinna używać String utf16.count zamiast znaków.count
Leo Dabus

0

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

Zauważ, że właściwość długości NSRange powinna używać String utf16.count zamiast znaków.count
Leo Dabus

0

Moim jedynym dodatkiem do listy odpowiedzi byłoby to, że dla Linuksa NSRegularExpressionnie istnieje, to jest tak naprawdęRegularExpression

    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

Kompiluje to z powodzeniem zarówno w systemie macOS, jak i Ubuntu.


Zauważ, że właściwość długości NSRange powinna używać String utf16.count zamiast znaków.count
Leo Dabus

0

Najlepsze rozwiązanie z najlepszym wynikiem dla

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

Lubię tworzyć rozszerzenia

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

}

stosowanie:

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

}

0

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

Następnie:

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

0

Perfect Regex, taki jak Google Email

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

2
ktokolwiek głosuje na moją odpowiedź, uprzejmie sprawdź swoją wiedzę. Użyłem tego wyrażenia regularnego w wielu kodach, a moi przyjaciele używają tego wyrażenia regularnego i działa świetnie. Zanim zagłosuję, odpowiedz uprzejmie, skomentuj i daj mi znać, co jest nie tak z tym wyrażeniem regularnym.
ami rt

Myślę, że mogę odpowiedzieć: Twoje wyrażenie regularne jest proste i nie pasuje do RFC. Na przykład wiadomości e-mail mogą zawierać cytaty, a nawet spacje w pierwszej części! Spójrz na haacked.com/archive/2007/08/21/…
Hugal31

1
Przykro mi, bracie, myślę, że powinieneś sprawdzić weryfikację adresu e-mail Google, nie ma sposobu, aby dodać spację w pierwszej części e-maila, a jeśli mój wyrażenie regularne jest błędne, to dlaczego nikt nie pisze i doskonała wyrażenie regularne.
ami rt

Według RFC 5322 „Hello world!” @ Example.com to poprawny adres e-mail. Rzeczywiście, poprawne wyrażenie regularne jest prawie niemożliwe. Nie każdy dostawca poczty pozostanie przy weryfikacji e-maili Google.
Hugal31

1
Tego chcę słuchać i dlatego wspomniałem pogrubioną czcionką, że powyżej wyrażenia regularnego jest jak Google. Dzięki
ami rt

-1

Lub możesz mieć rozszerzenie dla opcjonalnego tekstu UITextField:

jak używać:

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

rozbudowa:

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

Zauważ, że właściwość długości NSRange powinna używać String utf16.count zamiast znaków.count
Leo Dabus
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.