有人知道如何在Swift中验证电子邮件地址吗?我找到了这个代码:

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

但我无法翻译成斯威夫特。


当前回答

在Swift 5.7中,在Regex类的帮助下,我们可以以简单有效的方式验证电子邮件地址

private func isValidEmail(_ email: String) -> Bool {
      guard let emailRegex = try? Regex("[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}")  
      else { return false }
      return email.firstMatch(of: emailRegex) != nil
   }

我们还可以使用属性包装器来提高效率:

@propertyWrapper
struct EmailPropertyWrapper {
  private var _value: String
  var wrappedValue: String {
    get { return isValidEmail(_value) ? _value : String() }
    set { _value = newValue }
  }
  
  init(email: String) {
    _value = email
  }

  private func isValidEmail(_ email: String) -> Bool {
      guard let emailRegex = try? Regex("[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}")  
      else { return false }
      return email.firstMatch(of: emailRegex) != nil
   }
}

struct User {
  var name: String
  @EmailPropertyWrapper var email: String
  
  func validateProperty() -> Bool {
    if name.isEmpty || email.isEmpty { return false }
    return true
  }
}

let user = User(name: "Sy", email: .init(email: "wwdc@icloud.com"))

print(user.validateProperty())

其他回答

以上大多数正则表达式示例在电子邮件存在基本问题时都无法捕获错误。例如

h..1@nyu.edu -连续的点 ab1234@.nyu.edu - @后面的点 a.bcdnle12.@email.com - @前的点 .abc@email.com -以一个点开始

这是一个字符串扩展,我使用了更严格的规则使用正则表达式。

extension String {
    func isValidEmail() -> Bool {
        let emailRegEx = "^(?!\\.)([A-Z0-9a-z_%+-]?[\\.]?[A-Z0-9a-z_%+-])+@[A-Za-z0-9-]{1,20}(\\.[A-Za-z0-9]{1,15}){0,10}\\.[A-Za-z]{2,20}$"
        let emailPred = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
        return emailPred.evaluate(with: self)
   }
}

下面是我们如何为它编写测试用例。

XCTAssertFalse("ab1234@.nyu.edu".isValidEmail())
XCTAssertTrue("valid_email@email.com".isValidEmail())

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

作为String类扩展

斯威夫特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
    }
}

使用

if "rdfsdsfsdfsd".isValidEmail() {

}

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

就像这样使用它:

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

以下是目前Swiftmailer中一个非常简单的方法。其他大多数答案都是老掉牙的。

根据Swiftmailer文档: https://swiftmailer.symfony.com/docs/messages.html#quick-reference

use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Validation\RFCValidation;

$validator = new EmailValidator();
$validator->isValid("example@example.com", new RFCValidation()); //true

在我看来,这是迄今为止最简单、最健壮的方法。只需通过Composer安装egalias \EmailValidator库,它应该已经作为SwiftMailer的依赖项引入了。