在 Swift 中验证电子邮件地址的最佳实践是啥?

Posted

技术标签:

【中文标题】在 Swift 中验证电子邮件地址的最佳实践是啥?【英文标题】:What are best practices for validating email addresses in Swift?在 Swift 中验证电子邮件地址的最佳实践是什么? 【发布时间】:2014-10-03 14:29:10 【问题描述】:

我正在寻找在 Swift 中验证电子邮件(字符串)的最简单和最干净的方法。在 Objective-C 中我使用了这种方法,但是如果我将它重写为 Swift,我会在创建谓词时收到错误“无法解析格式字符串”。

- (BOOL) validateEmail: (NSString *) candidate 
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]2,6"; 
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex]; 

    return [emailTest evaluateWithObject:candidate];

【问题讨论】:

请始终发布不起作用的代码。 【参考方案1】:

看起来很简单。如果您在 Swift 转换中遇到问题,看看您实际尝试过的内容可能会有所帮助。

这对我有用:

func validateEmail(candidate: String) -> Bool 
    let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]2,6"
    return NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluateWithObject(candidate)


validateEmail("test@google.com")     // true
validateEmail("invalid@@google.com") // false

【讨论】:

嗯,区别仅在于我们如何将 emailRegex 插入谓词中... func isEmailValid(strEmail: String) -> Bool var strEmailRegex = "[A-Z0-9a-z\\ ._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]2,6" var predicateEmail = NSPredicate(format: "SELF MATCHES (strEmailRegex )") 返回 predicateEmail.evaluateWithObject(strEmail) 正确 - 因为您没有向 NSPredicate 初始化程序提供任何格式参数,所以这不起作用。您仍然需要使用%@ 并通过最后的可变参数列表传递它。 谢谢!我现在明白了——我只需要再看一下 NSPredicate 的 init 函数 :) 没问题,乐于助人。 您的正则表达式不认为像 !#$%&'*+/=?^_`|~ 这样的字符是允许的,并且地址不得包含 .作为第一个/最后一个字符。【参考方案2】:

Swift 3.0 版本

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


validateEmail("test@google.com")     // true
validateEmail("invalid@@google.com") // false

【讨论】:

【参考方案3】:
extension String

    func isEmail() -> Bool
    
        let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]2,6"
        return NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluateWithObject(self)
    

【讨论】:

【参考方案4】:

这是适用于每个电子邮件域的扩展。

例如:.com.co.uk.co.in

extension String 

     func isValidEmail() -> Bool 

         let emailRegEx = "^[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])?)*$"
         let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
         return emailTest.evaluateWithObject(self)
     

【讨论】:

【参考方案5】:

只想在这里投入我的两分钱,然后用曲线球击中你:

您真的要这样验证您的电子邮件地址吗?

请参阅此blogpost,它表明检查电子邮件是否有效所需要做的就是检查它是否有一个@ 符号,或者最多是一个@,在某些时候后面跟着一个.

/.+@.+\..+/i

【讨论】:

【参考方案6】:
      class func isValidEmail(email:String)-> Bool
      
          let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]2,4"
          var emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
          let result = emailTest!.evaluateWithObject(email)
          return result
      

【讨论】:

【参考方案7】:

Craigs 的答案很有效,如果有人在努力实现它,这里是 textFieldDidEndEditing 函数调用它。 (需要 UITextFieldDelegate)

func textFieldDidEndEditing(textField: UITextField)

    if validateEmail(emailAddress.text)
    
        println("valid")
    
    else
    
        println("NOT valid")
    


func validateEmail(candidate: String) -> Bool 
    let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]2,6"
    return NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluateWithObject(candidate)

【讨论】:

【参考方案8】:

Swift 4 简单设置:

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

添加

UITextFieldDelegate

在 viewDidLoad 中:

yourTextField.delegate = self

用法:

func textFieldDidEndEditing(_ textField: UITextField) 

    guard let validEmailAddress = yourTextFiled.text else  return 
    if !(validEmailAddress.isEmail) 
        //is invalid address
     else 
       //is valid address
  

【讨论】:

【参考方案9】:

我使用 NSDataDetector API。这里的很多答案都不支持电子邮件地址中允许的' 等字符。

extension String 
    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")
    

例如

"foo@bar.com".isEmail  // true
"foo.mc'doo@foo-bar.com".isEmail   // true

我还使用了这个来自 android SDK 的正则表达式,效果很好:

[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]1,256\\@[a-zA-Z0-9][a-zA-Z0-9\\-]0,64(\\.[a-zA-Z0-9][a-zA-Z0-9\\-]0,25)+

为什么 Apple 不只是在 String 上包含用于电子邮件验证的方法是一个谜。

【讨论】:

【参考方案10】:
func isValidEmail(testStr: String) -> Bool 
    print("valid Email-ID: \(testStr)")
    let emailRegEx = "[A-Za-z0-9_%+-]+@[A-Za-z0-9._]+\\.[A-Za-z]2,"
    let emailTest = NSPredicate(format: "SELF MATCHES %@",emailRegEx)
    return emailTest.evaluateWithObject(testStr)

func textFieldDidEndEditing(textField: UITextField) 
    if isValidEmail(txt_EmailID.text!)
        print("Email is Valid")
    else
        print("Email is not valid")
    


// creat done button outlet

@IBAction func btn_Done(sender: AnyObject) 
    validated()


【讨论】:

以上是关于在 Swift 中验证电子邮件地址的最佳实践是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 Rails 中验证多封电子邮件和处理错误的最佳方法是啥?

Swift 中全局变量和函数的最佳实践是啥?

在objective-c或swift中覆盖pod文件方法的最佳实践是啥?

当前在 PHP 中防止电子邮件注入攻击的最佳实践是啥?

Swift 风格:函数返回您需要的类型的可选类型以便继续,处理此问题的最佳实践是啥?

MVC 验证 - 使用服务层保持 DRY - 最佳实践是啥?