ios - Come convalidare un indirizzo e-mail in swift?




validation email (21)

Questa è la versione aggiornata per Swift 2.0 - 2.2

 var isEmail: Bool {
    do {
        let regex = try NSRegularExpression(pattern: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected][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
    }
}

Qualcuno sa come convalidare un indirizzo e-mail in Swift? Ho trovato questo codice:

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

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

    NSString *regExPattern = @"[A-Z0-9a-z._%+-][email protected][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;
    }
}

ma non posso tradurlo in Swift.


//Email validation
func validateEmail(enterEmail:String) -> Bool{
    let emailFormat = "[A-Z0-9a-z._%+-][email protected][A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
    let emailPredicate = NSPredicate(format:"SELF MATCHES %@",emailFormat)
    return emailPredicate.evaluate(with:enterEmail)
}

100% funzionante e testato


È possibile trovare utile un framework di convalida del modulo riutilizzabile. Ha creato regole di campo e tu crei le tue regole di convalida personalizzate implementando il protocollo FieldValidator.

Esempio di seguito: import UIKit import FormValidationKit

class ViewController: UIViewController, FormValidationDelegate, FieldValidatorDelegate {var formValidator: FormValidator?

var usernameValidator : FieldValidator?
var emailValidator : FieldValidator?

@IBOutlet weak var usernameTf: UITextField!
@IBOutlet weak var emailTf: UITextField!

@IBAction func didTapButton(sender: AnyObject) {

    formValidator?.submit()
}

override func viewDidLoad() {
    super.viewDidLoad()
    //Initialize the form validator
    formValidator = FormValidator()

    //Create field validators
    //Set nil to first field validator
    usernameValidator = FieldValidator(inputValue: { () -> AnyObject in
        return self.usernameTf.text
    }, rules: [Required(validationError: ValidationError(hint: "Field is required"))], nextValidator: nil, form: formValidator!)
    usernameValidator!.delegate = self


    emailValidator = FieldValidator(inputValue: { () -> AnyObject in
        return self.emailTf.text
    }, rules: [Email(validationError: ValidationError(hint: "Proper email format"))], nextValidator: usernameValidator!, form: formValidator!)
    emailValidator!.delegate = self

    formValidator?.initialValidator = emailValidator!
    formValidator?.delegate = self
}

//per field error delegate method
func didEvaluateField(field: FieldValidator, errors: Array<String>, form: FormValidator) {
    switch field {
    case usernameValidator!:
        println("Username field error")
        break;
    case emailValidator!:
        println("Username field error")
    default:
        println("Field error")
    }
}

//form delegate methods
func didPassFormValidation(form: FormValidation) {
    println(__FUNCTION__)
}

func didFailFormValidation(form: FormValidation) {
    println(__FUNCTION__)
}

Link Github qui


Sembra funzionare anche ...

let regex = "[A-Z0-9a-z._%+-][email protected][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
}

Ecco una combinazione delle due risposte più votate con la regex corretta: un'estensione di stringa che utilizza il predicato in modo da poter chiamare string.isEmail

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

Per swift 2.1: funziona correttamente con email foo @ bar

extension String {
    func isValidEmail() -> Bool {
        do {
            let regex = try NSRegularExpression(pattern: "[A-Z0-9a-z._%+-][email protected][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
        }
    }
}

Ecco un'estensione in Swift 3

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

Basta usarlo in questo modo:

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

Se stai cercando una soluzione semplice e pulita per farlo, dovresti dare un'occhiata a https://github.com/nsagora/validation-components .

Contiene un predicato di convalida della posta elettronica che è facile da integrare nel codice:

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

Dietro il cofano utilizza 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])+)\\])"

Ecco un metodo basato su rangeOfString :

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

Nota: lunghezza TLD aggiornata.

Ecco il RegEx definitivo per e-mail come da RFC 5322, si noti che questo è il migliore non utilizzato perché controlla solo la sintassi di base degli indirizzi e-mail e non controlla che il dominio di primo livello esista.

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

Vedi Regular-Expressions.info per informazioni più complete sulle e-mail RegEx.

Si noti che non è necessario eseguire l'escape come richiesto da una lingua come Objective-C o Swift.


Dato che ora ci sono così tanti nomi di dominio di primo livello strani, smetto di controllare la lunghezza del dominio in alto ...

Ecco cosa uso:

extension String {

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

Come estensione di una classe String

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.!#$%&'*+/=?^_`{|}~-][email protected][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
    }
}

uso

if "rdfsdsfsdfsd".isValidEmail() {

}

Modifica, aggiornata per Swift 3:

func validateEmail(enteredEmail:String) -> Bool {

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

}

Risposta originale per Swift 2:

func validateEmail(enteredEmail:String) -> Bool {

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

}

Funziona bene.


Ci sono molte risposte giuste qui, ma molte delle "regex" sono incomplete e può capitare che un'e-mail come: "nome @ dominio" restituisca un'e-mail valida, ma non lo è. Ecco la soluzione completa:

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

Oppure puoi avere un'estensione per il testo opzionale di UITextField:

come usare:

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

estensione:

extension Optional where Wrapped == String {
    func isEmailValid() -> Bool{
        guard let email = self else { return false }
        let emailPattern = "[A-Za-z-0-9.-_][email protected][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
    }
}

E per Swift 3 :

extension String {
    func isValidEmail() -> Bool {
        let regex = try? NSRegularExpression(pattern: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected][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
    }
}

Preferisco usare un'estensione per questo. Inoltre, questo url http://emailregex.com può aiutarti a verificare se la regex è corretta. In effetti, il sito offre diverse implementazioni per alcuni linguaggi di programmazione. Condivido la mia implementazione per Swift 3 .

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

Ecco la soluzione ragionevole:

"LA SOLUZIONE RAGIONEVOLE"

1 - evita i molti errori di regex che vedi spesso in questi suggerimenti

2 - non consente email stupide come "x @ x" che sono tecnicamente valide, ma sono completamente stupide - e il personale di supporto, ecc., Rifiuterebbe comunque in ogni caso. Se hai bisogno (per quale scopo?) Di una soluzione che permetta email stupide, usa un'altra soluzione.

3 - è estremamente comprensibile , per quanto si possa sperare

4 - È BACIO, affidabile e testato per la distruzione su app commerciali con un numero enorme di utenti

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,6}"
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
    }
}

Spiegazione:

Nella seguente descrizione, "OC" significa carattere ordinario: quindi, una lettera o una cifra.

__firstpart ... deve iniziare e finire con un OC. Per i personaggi nel mezzo puoi avere alcuni caratteri insoliti come il trattino basso, ma l'inizio e la fine devono essere OC. (Va bene avere solo un OC e basta, esempio [email protected])

__serverpart ... Hai sezioni come "blah". quale ripetizione. (Quindi, mail.city.fcu.edu tipo di cosa.) Le sezioni devono iniziare e finire con un OC, ma nel mezzo si può anche avere un trattino "-". (Se si desidera consentire ad altri caratteri insoliti in là, ad esempio sottolineatura, è sufficiente aggiungerlo prima del trattino.) È OK avere una sezione che è solo un OC. (Come in [email protected] o [email protected]) È possibile avere fino a cinque sezioni; devi averne uno Infine il TLD (.com o simili) è strettamente composto da 2 a 6 lettere.

Nota che tieni semplicemente il predicato come globale (banale in Swift), non c'è bisogno di costruirlo ogni volta.


Risposta aggiornata @Arsonik risponde a Swift 2.2, utilizzando un codice meno dettagliato rispetto ad altre soluzioni offerte:

extension String {
    func isValidEmail() -> Bool {
        let regex = try? NSRegularExpression(pattern: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected][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
    }
}

Vorrei usare NSPredicate :

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

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

per le versioni di Swift precedenti alla 3.0:

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

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

per le versioni di Swift precedenti alla 1.2:

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

    if let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx) {
        return emailTest.evaluateWithObject(testStr)
    }
    return false
}

Regex perfetto come Google Email

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

Xcode 8 ora lo gestisce come segue e si presenta così nel menu a discesa del metodo:





ios validation email swift