如何验证一个电子邮件地址在swift?

有人知道如何在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;
}
}

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

264202 次浏览

我将使用NSPredicate:

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


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

对于Swift 3.0之前的版本:

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


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

对于Swift 1.2之前的版本:

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


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

下面是一个基于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)
return range != nil
}

备注:更新TLD长度。

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

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

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

注意,在Objective-C或Swift等语言中没有转义。

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

下面是两个投票最多的答案与正确的正则表达式的融合:一个使用谓词的字符串扩展,因此您可以调用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)
}
}

我为输入验证设计了一个库,其中一个“模块”可以让你轻松地验证一堆东西…

例如,要验证一封电子邮件:

let emailTrial = Trial.Email
let trial = emailTrial.trial()


if(trial(evidence: "test@test.com")) {
//email is valid
}

SwiftCop是库…希望能有所帮助!

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

因为现在有这么多奇怪的顶级域名,我不再检查顶级域名的长度…

以下是我使用的方法:

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

这里有很多正确答案,但许多“正则表达式”是不完整的,可能会发生像“name@domain”这样的电子邮件结果是有效的电子邮件,但它不是。这里是完整的解决方案:

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

编辑,针对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)


}

它工作得很好。

似乎也有用……

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
}

我建议使用它作为String的扩展:

extension String {
public 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: 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")
}

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

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

如果你正在寻找一个干净简单的解决方案,你应该看看https://github.com/nsagora/validation-components

它包含一个电子邮件验证谓词,很容易集成在你的代码:

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])+)\\])"

@JeffersonBe的答案是接近的,但返回true如果字符串是“包含someone@something.com一个有效的电子邮件”,这不是我们想要的。下面是String上的一个扩展,它工作得很好(并且允许测试有效的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
}

对于斯威夫特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。

我更喜欢用扩展名。此外,这个url http://emailregex.com可以帮助你测试regex是否正确。事实上,该站点为某些编程语言提供了不同的实现。我分享了我的斯威夫特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)
}
}

(序言。注意,在某些情况下,你现在可以使用iOS内置的解决方案:https://multithreaded.stitchfix.com/blog/2016/11/02/email-validation-swift/)


唯一的解决办法:

1 -它避免了在示例代码中经常看到的可怕的正则表达式错误

2 -它允许荒谬的电子邮件,如"x@x"

(如果出于某种原因,你需要一个允许“x@x”之类无意义字符串的解决方案,请使用另一个解决方案。)

3 -代码是非常可以理解的

4 -它是KISS,可靠,和 . 0在商业应用上测试了大量用户的破坏

5 - 谓词是一个全局变量,就像苹果说一样

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,8}"
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() ?? false
}
}

就是这么简单。

对于regex新手的解释:

在这个描述中,"OC"表示普通字符—字母或数字。

__firstpart……必须用OC 开始和结束。对于中间中的字符,你可以使用某些字符,例如下划线,但开始和结束必须是一个OC。(然而,只有一个OC是好吧,例如:j@blah.com)

__serverpart……你有部分像“blah”;重复。(例如,mail.city.fcu.edu)。section必须使用OC 开始和结束,但是在中间中你也可以使用破折号 "-"。它是好吧,有一个只是一个 OC的section。(例如,w.campus.edu)你最多可以有五个section,你必须只有一个。最后,TLD(例如。com)在大小中严格是2到8。(显然,只要把&;8&;由您的支持部门推荐。)


重要!

您必须保持谓词为全局,不要每次都构建它。

注意,这是文档中的这是苹果在整个问题上提到的第一件事

不缓存谓词的建议是不启动的。


非英文字母

当然,如果你处理的是非英语字母,要适当调整。

创建简单的扩展:

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等…

完美的正则表达式,如谷歌电子邮件

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

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

或者你可以扩展可选文本UITextField:

使用方法:

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

扩展:

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

100%工作和测试

最好的解决方案,最好的结果

快4.倍

 extension String {


func validateAsEmail() -> Bool {
let emailRegEx = "(?:[a-zA-Z0-9!#$%\\&‘*+/=?\\^_`{|}~-]+(?:\\.[a-zA-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])+)\\])"


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

这是@Fattie的“合理解决方案”的新版本,在Swift 4.1的一个名为String+Email.swift的新文件中测试:

import Foundation


extension String {
private static let __firstpart = "[A-Z0-9a-z]([A-Z0-9a-z._%+-]{0,30}[A-Z0-9a-z])?"
private static let __serverpart = "([A-Z0-9a-z]([A-Z0-9a-z-]{0,30}[A-Z0-9a-z])?\\.){1,5}"
private static let __emailRegex = __firstpart + "@" + __serverpart + "[A-Za-z]{2,6}"


public var isEmail: Bool {
let predicate = NSPredicate(format: "SELF MATCHES %@", type(of:self).__emailRegex)
return predicate.evaluate(with: self)
}
}

所以它的用法很简单:

let str = "mail@domain.com"
if str.isEmail {
print("\(str) is a valid e-mail address")
} else {
print("\(str) is not a valid e-mail address")
}

我只是不喜欢在String对象中添加func,因为作为电子邮件地址是它们固有的(或不是)。因此,根据我的理解,Bool属性比func更适合。

我喜欢扩展

   extension String {


func isValidateEmail() -> 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: self)
}


}

用法:

if emailid.text!.isValidateEmail() == false(){
//do what ever you want if string is not matched.


}

我改进了@Azik的答案。我允许使用准则允许的更多特殊字符,并返回一些无效的额外边缘情况。

小组认为这里只允许._%+-在局部部分是不正确的,根据指导方针。参见@Anton Gogolev对问题的回答或参见下文:

电子邮件地址的本地部分可以使用这些ASCII中的任何一个 人物:< / p >

  • 大写和小写拉丁字母AZaz;

  • 数字09;

  • 特殊字符!#$%&'*+-/=?^_`{|}~;

  • . .,前提是它不是第一个或最后一个字符,除非引用,并且除非引用,它不会连续出现(例如。 不允许使用John..Doe@example.com,但允许使用"John..Doe"@example.com 允许);李< / p > < / >

  • 空格和"(),:;<>@[\]字符被允许 限制(它们只允许在带引号的字符串中,例如 在下面的段落中描述,此外,还有一个反斜杠或 双引号前必须加反斜杠); 允许注释

  • local-part两端有括号;如。 john.smith(comment)@example.com(comment)john.smith@example.com 都等价于john.smith@example.com;

我使用的代码将不允许限制性的特殊字符,但将允许比这里的大多数答案更多的选项。我更喜欢更宽松的验证,而不是谨慎的错误。

if enteredText.contains("..") || enteredText.contains("@@")
|| enteredText.hasPrefix(".") || enteredText.hasSuffix(".con"){
return false
}


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: enteredText)

Swift 4.2的使用

extension String {
func isValidEmail() -> Bool {
let regex = try? NSRegularExpression(pattern: "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$", options: .caseInsensitive)
return regex?.firstMatch(in: self, options: [], range: NSMakeRange(0, self.count)) != nil
}
func isValidName() -> Bool{
let regex = try? NSRegularExpression(pattern: "^[\\p{L}\\.]{2,30}(?: [\\p{L}\\.]{2,30}){0,2}$", options: .caseInsensitive)


return regex?.firstMatch(in: self, options: [], range: NSMakeRange(0, self.count)) != nil
} }

和使用

if (textField.text?.isValidEmail())!
{
// bla bla
}
else
{


}

斯威夫特4.2和Xcode 10.1

//Email validation
func isValidEmail(email: String) -> Bool {
let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
var valid = NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: email)
if valid {
valid = !email.contains("Invalid email id")
}
return valid
}


//Use like this....
let emailTrimmedString = emailTF.text?.trimmingCharacters(in: .whitespaces)
if isValidEmail(email: emailTrimmedString!) == false {
SharedClass.sharedInstance.alert(view: self, title: "", message: "Please enter valid email")
}

如果你想使用SharedClass。

//This is SharedClass
import UIKit
class SharedClass: NSObject {


static let sharedInstance = SharedClass()


//Email validation
func isValidEmail(email: String) -> Bool {
let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
var valid = NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: email)
if valid {
valid = !email.contains("Invalid email id")
}
return valid
}


private override init() {


}
}

并调用这样的函数....

if SharedClass.sharedInstance. isValidEmail(email: emailTrimmedString!) == false {
SharedClass.sharedInstance.alert(view: self, title: "", message: "Please enter correct email")
//Your code here
} else {
//Code here
}

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

根据Swiftmailer文档: https://swiftmailer.symfony.com/docs/messages.html#quick-reference < / p >
use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Validation\RFCValidation;


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

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

对于那些还在寻找答案的人,请看看下面的框架;

ATGValidator

它是一个基于规则的验证框架,可以处理大部分开箱即用的验证。最重要的是,它有form validator,它支持同时验证多个文本字段。

要验证电子邮件字符串,请使用以下方法;

"abcd.hhs@some.com".satisfyAll(rules: [StringRegexRule.email]).status

如果你想验证从文本字段的电子邮件,尝试下面的代码;

textfield.validationRules = [StringRegexRule.email]
textfield.validationHandler = { result in
// This block will be executed with relevant result whenever validation is done.
print(result.status, result.errors)
}
// Below line is to manually trigger validation.
textfield.validateTextField()

如果您想在文本框中输入或当焦点更改到另一个字段时验证它,请添加以下行之一;

textfield.validateOnInputChange(true)
// or
textfield.validateOnFocusLoss(true)

请在链接中查看自述文件以获得更多用例。

Swift 5中最简单的方法

extension String {
var isValidEmail: Bool {
NSPredicate(format: "SELF MATCHES %@", "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}").evaluate(with: self)
}
}

例子

"kenmueller0@gmail.com".isValidEmail

返回……

true

斯威夫特5

 func isValidEmailAddress(emailAddressString: String) -> Bool {


var returnValue = true
let emailRegEx = "[A-Z0-9a-z.-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,3}"


do {
let regex = try NSRegularExpression(pattern: emailRegEx)
let nsString = emailAddressString as NSString
let results = regex.matches(in: emailAddressString, range: NSRange(location: 0, length: nsString.length))


if results.count == 0
{
returnValue = false
}


} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
returnValue = false
}


return  returnValue
}

然后:

let validEmail = isValidEmailAddress(emailAddressString: "your@email.com")
print(validEmail)

Swift 5 -可伸缩的验证层

使用此层,您将轻松地在任何文本字段上获得惊人的验证。

只需遵循以下流程即可。

1. 添加这些枚举:

import Foundation


enum ValidatorType
{
case email
case name
// add more cases ...
}


enum ValidationError: Error, LocalizedError
{
case invalidUserName
case invalidEmail
// add more cases ...


var localizedDescription: String
{
switch self
{
case .invalidEmail:
return "Please kindly write a valid email"
case .invalidUserName:
return "Please kindly write a valid user name"
}
}
}

2. 将此功能添加到String:

extension String
{
// MARK:- Properties


var isValidEmail: 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: self)
}


// MARK:- Methods


func validatedText(_ validationType: ValidatorType) throws
{
switch validationType
{
case .name:
try validateUsername()
case .email:
try validateEmail()
}
}


// MARK:- Private Methods


private func validateUsername() throws
{
if isEmpty
{
throw ValidationError.invalidUserName
}
}


private func validateEmail() throws
{
if !isValidEmail
{
throw ValidationError.invalidEmail
}


// add more validations if you want like empty email
}
}

3.向UITextField添加以下功能:

import UIKit


extension UITextField
{
func validatedText(_ validationType: ValidatorType) throws
{
do
{
try text?.validatedText(validationType)
}
catch let validationError
{
shake()
throw validationError
}
}


// MARK:- Private Methods


private func shake()
{
let animation = CABasicAnimation(keyPath: "position")
animation.duration = 0.1
animation.repeatCount = 5
animation.fromValue = NSValue(cgPoint: CGPoint(x: center.x + 6, y: center.y))
animation.toValue = NSValue(cgPoint: CGPoint(x: center.x - 6, y: center.y))
layer.add(animation, forKey: "position")
}
}

使用

import UIKit


class LoginVC: UIViewController
{
// MARK: Outlets


@IBOutlet weak var textFieldEmail: UITextField!


// MARK: View Controller Life Cycle


override func viewDidLoad()
{
super.viewDidLoad()
}


// MARK: Methods


private func checkEmail() -> Bool
{
do
{
try textFieldEmail.validatedText(.email)
}
catch let error
{
let validationError = error as! ValidationError
// show alert to user with: validationError.localizedDescription
return false
}


return true
}


// MARK: Actions


@IBAction func loginTapped(_ sender: UIButton)
{
if checkEmail()
{
let email = textFieldEmail.text!
// move safely ...
}
}
}

这是一个最新的游乐场兼容版本,使用标准库,所以你不需要维护一个正则表达式:

import Foundation


func isValid(email: String) -> Bool {
do {
let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
let range = NSRange(location: 0, length: email.count)
let matches = detector.matches(in: email, options: .anchored, range: range)
guard matches.count == 1 else { return false }
return matches[0].url?.scheme == "mailto"
} catch {
return false
}
}


extension String {
var isValidEmail: Bool {
isValid(email: self)
}
}


let email = "test@mail.com"
isValid(email: email) // prints 'true'
email.isValidEmail // prints 'true'

@.做一个简单的测试,并发送确认电子邮件。

考虑一下:

  • 世界上有一半的人使用非ascii字符。
  • 正则表达式是缓慢和复杂的。顺便说一下,至少检查字符/字母/Unicode范围,而不是az。
  • 因为RFC规则和相应的正则表达式太复杂,所以你无法提供完全验证。

我用的是这个基本的检查:

// similar to https://softwareengineering.stackexchange.com/a/78372/22077
import Foundation


/**
Checks that
- length is 254 or less (see https://stackoverflow.com/a/574698/412916)
- there is a @ which is not the first character
- there is a . after the @
- there are at least 4 characters after the @
*/
func isValidEmail(email: String) -> Bool {
guard email.count <= 254 else {
return false
}
let pos = email.lastIndex(of: "@") ?? email.endIndex
return (pos != email.startIndex)
&& ((email.lastIndex(of: ".") ?? email.startIndex) > pos)
&& (email[pos...].count > 4)
}


print(isValidEmail(email: "アシッシュ@ビジネス.コム")) // true

请注意,

  • 它比regex和NSDataDetector快得多。

  • 它正确地报告以下是有效的:

Håkan.Söderström@malmö.se"
punnycode@XN--0ZWM56D.XN--HGBK6AJ7F53BBA"
试@例子.测试.مثال.آزمایشی"
foo.bar+something@blah.com"
m@foo.co.uk
  • 它错误地将以下内容报告为无效——因为它们实际上是有效的,但可能是用户错误的产物:
a @ b
a@b

相关:

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

  1. h..1@nyu.edu -连续的点
  2. ab1234@.nyu.edu - @后面的点
  3. a.bcdnle12.@email.com - @前的点
  4. .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())