如何快速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
您可以扩展以下扩展到任何你需要的: isValidPhoneNumber
, isValidPassword
等…
似乎也工作…
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,}"