如何快速validation电子邮件地址?

有谁知道如何在Swift中validation电子邮件地址? 我发现这个代码:

- (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。

我会使用NSPredicate

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

对于早于3.0的Swift版本:

  func isValidEmail(testStr:String) -> Bool { // print("validate calendar: \(testStr)") let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}" let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx) return emailTest.evaluateWithObject(testStr) } 

对于早于1.2版本的Swift版本:

  class func isValidEmail(testStr:String) -> Bool { println("validate calendar: \(testStr)") let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}" if let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx) { return emailTest.evaluateWithObject(testStr) } return false } 

编辑,更新为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) } 

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

这工作正常。

作为类扩展

 extension String { func isValidEmail() -> Bool { let regex = 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, error: nil) return regex?.firstMatchInString(self, options: nil, range: NSMakeRange(0, countElements(self))) != nil } } 

用法

 if "rdfsdsfsdfsd".isValidEmail() { } 

SWIFT 3/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: characters.count)) != nil } } 

这是两个最正确的答案与正确的正则expression式的一个导火索:一个string扩展使用谓词,所以你可以调用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) } } 

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

如果你正在寻找一个干净和简单的解决scheme来做到这一点,你应该看看https://github.com/nsagora/validation-components

它包含一个电子邮件validation谓词,它很容易整合到你的代码中:

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

在引擎盖后面,它使用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])+)\\])" 

这里是一个基于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 } 

注意:更新的TLD长度。

以下是根据RFC 5322确定的电子邮件RegEx,请注意,最好不要使用它,因为它只检查电子邮件地址的基本语法,而不检查是否存在顶级域名。

 (:[A-Z0-9#$%& '* + / = ^ _`{|}〜 -  +(?!\ [A-Z0-9#$%&!]'?* + / = ^ _`{|}?〜 - ] +)*
   |  “(?:[\ x01- \ X08 \ X0B \ X0C \ x0e- \ X1F \ X21 \ x23- \ x5b \ x5d- \ 0x7F部分]
       |  \\ [\ x01- \ X09 \ X0B \ X0C \ x0e- \ 0x7F部分])*“)
 (?:[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- \ 0x7F部分]
           |  \\ [\ x01- \ X09 \ X0B \ X0C \ x0e- \ 0x7F部分])+)
      \])

有关电子邮件RegExs的更完整信息,请参阅Regular-Expressions.info。

请注意,按照Objective-C或Swift语言的要求不能转义。

我会build议使用它作为string的扩展:

 extension String { public var isEmail: Bool { let dataDetector = try? NSDataDetector(types: NSTextCheckingType.Link.rawValue) let firstMatch = dataDetector?.firstMatchInString(self, options: NSMatchingOptions.ReportCompletion, range: NSRange(location: 0, length: length)) return (firstMatch?.range.location != NSNotFound && firstMatch?.URL?.scheme == "mailto") } public var length: Int { return self.characters.count } } 

并使用它:

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

来源: https : //github.com/goktugyil/EZSwiftExtensions/blob/master/Sources/StringExtensions.swift

我更喜欢使用扩展。 此外,这个urlhttp://emailregex.com可以帮助你testing正则expression式是否正确。 实际上,该网站为某些编程语言提供了不同的实现。 我分享了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) } } 

这里有很多正确的答案,但是许多“正则expression式”是不完整的,可能会发生这样一封电子邮件,如:“name @ domain”会生成有效的电子邮件,但事实并非如此。 这里完整的解决scheme:

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

对于迅速2.1:这与电子邮件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 } } } 

我做了一个为inputvalidation而devise的库,其中一个“模块”允许您轻松validation一堆东西…

例如validation电子邮件:

 let emailTrial = Trial.Email let trial = emailTrial.trial() if(trial(evidence: "test@test.com")) { //email is valid } 

SwiftCop是图书馆…希望它有帮助!

这是合理的解决scheme:

“合理的解决scheme”

1 – 它避免了这些build议中经常看到的许多非常简单的正则expression式错误

2 – 它不允许愚蠢的电子邮件,如技术上有效的“x @ x”,但是完全愚蠢,您的服务器,支持人员等将会拒绝。 如果你需要(为了什么目的?)一个允许愚蠢的电子邮件的解决scheme,使用另一种解决scheme。

3 – 这是非常可以理解的,尽可能多的希望

4 – KISS,可靠,经过testing

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

说明:

在这里,“OC”是指普通字符:字母或数字。

__firstpart …必须以OC开始和结束。 对于中间的字符,你可以有一些不寻常的字符,如下划线,但是开始和结束必须是OC。 (只有一个OC就可以了,例如j@blah.com)

__serverpart …你有部分“blah”。 重复。 (所以,mail.city.fcu.edutypes的东西。)部分必须开始和结束一个OC,但在中间,你也可以有短划线“ – ”。 (如果你想允许其他不常用的字符,比如说下划线,只要在短划线之前加上就可以了)。只有一个OC是可以的。 (如joe@x.com或joe@w.campus.edu)最多可以有五个部分; 你必须有一个。 最后TLD(.com或类似的)是严格的2到6个字母。

请注意,您只需将谓词保持为全局(在Swift中是微不足道的),不需要每次构build它。

创build简单的扩展:

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

例:

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

您可以扩展以下扩展到任何你需要的: isValidPhoneNumberisValidPassword等…

似乎也工作…

 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 } 

更新答案@Arsonik回答Swift 2.2,使用比其他提供的解决schemeless冗长的代码:

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

@ JeffersonBe的答案是接近的,但是如果string是“某个包含someone@something.com一个有效的电子邮件”这个string,则返回true ,这不是我们想要的。 以下是对string的扩展,运行良好(并允许testing有效的phoneNumber和其他数据检测器启动。

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

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

我唯一的答案列表是除Linux之外, NSRegularExpression不存在,它实际上是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 

这在macOS和Ubuntu上成功编译。

您可能会发现有用的可重复使用的表单validation框架。 它已经构build了它的现场规则,并通过实施FieldValidator协议来创build自定义validation规则。

下面的例子:import UIKit import FormValidationKit

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

Github链接在这里

由于现在有这么多怪异的顶级域名,我停止检查顶级域的长度…

这是我使用的:

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

基本的 NSRegularExpression, Swift 3 ,请参阅IBM Swift Sandbox链接:

 let pattern = "[^@]+@[a-zA-Z0-9-.]+\\.[a-zA-Z]{2,}" var regex: NSRegularExpression? do { regex = try NSRegularExpression(pattern: pattern, options: []) } catch let error { print("regex failed for \(pattern), error \(error)") } let testEmail = "name@test.ca" let matches = regex!.matches(in: testEmail, options: .withTransparentBounds, range: NSMakeRange(0, testEmail.characters.count)) if matches.count != 0 { print("Email appears to be valid") } else { print("Email does not appear to be valid") } 

IBM沙盒: 基本Swift NSRegularExpression电子邮件validation

完美的正则expression式像Google电子邮件

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