提问人:giorgionocera 提问时间:8/24/2014 最后编辑:Nareshgiorgionocera 更新时间:6/19/2023 访问量:283440
如何在 swift 中验证电子邮件地址?
How to validate an e-mail address in 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;
}
}
但我无法将其翻译成 Swift。
答:
我会使用 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)
}
对于 3.0 之前的 Swift 版本:
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)
}
对于 1.2 之前的 Swift 版本:
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
}
评论
return emailTest.evaluateWithObject(testStr)
== true
这是一个基于以下方法的方法: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 的电子邮件的最终正则表达式,请注意,最好不要使用它,因为它只检查电子邮件地址的基本语法,而不检查顶级域是否存在。
(?:[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])+) \])
有关电子邮件正则表达式的更多信息,请参阅 Regular-Expressions.info。
请注意,没有 Objective-C 或 Swift 等语言所要求的转义。
评论
.engineer
作为类扩展String
SWIFT 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() {
}
评论
countElements
是现在count
这是 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 扩展,因此您可以调用 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: "[email protected]")) {
//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)
}
它工作正常。
评论
我建议将其用作 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 "[email protected]".isEmail { // true
print("Hold the Door")
}
评论
更新了 Swift 2.2 的答案@Arsonik答案,使用比其他解决方案更详细的代码:
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 = "[email protected]"
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的答案很接近,但如果字符串是“包含 [email protected] 有效电子邮件的东西”,则返回,这不是我们想要的。以下是 String 上的一个扩展,它运行良好(并允许测试有效的 phoneNumber 和其他数据检测器以启动。true
/// 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
}
评论
我对回复列表的唯一补充是,对于 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 可以帮助您测试正则表达式是否正确。事实上,该网站为某些编程语言提供了不同的实现。我分享了我对 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)
}
}
评论
(序言。请注意,在某些情况下,您现在可以使用此 iOS 内置的解决方案:https://multithreaded.stitchfix.com/blog/2016/11/02/email-validation-swift/ )
唯一的解决方案:
1 - 它避免了示例代码中经常出现的可怕的正则表达式错误
2 - 它不允许荒谬的电子邮件,例如“x@x”
(如果出于某种原因,您需要一个允许无意义字符串(如“x@x”)的解决方案,请使用其他解决方案。
3 - 代码非常容易理解
4 - 它是 KISS,可靠,并在拥有大量用户的商业应用程序上经过测试以破坏
5 - 谓词是全局的,正如 Apple 所说的那样
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
}
}
就这么简单。
对正则表达式新手的解释:
在此描述中,“OC”表示普通字符 - 字母或数字。
__firstpart......必须以 OC 开头和结尾。对于中间的字符,您可以使用某些字符,例如下划线,但开头和结尾必须是 OC。 (但是,只有一个 OC 是可以的,仅此而已,例如:[email protected])
__serverpart......你有像“废话”这样的部分,它们重复。(例如,mail.city.fcu.edu。这些部分必须以 OC 开头和结尾,但在中间也可以有一个破折号“-”。(例如,w.campus.edu)您最多可以有五个部分,您必须有一个。最后,TLD(如 .com)的大小严格为 2 到 8。(显然,只需根据支持部门的首选更改“8”即可。
重要!
您必须将谓词保留为全局,不要每次都构建它。
请注意,这是Apple在文档中提到的关于整个问题的第一件事。
不缓存谓词的建议是非启动器。
非英文字母
当然,如果您处理非英语字母,请进行适当的调整。
评论
创建简单扩展:
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
}
}
例:
"[email protected]".isValidEmail //true
"b@bb".isValidEmail //false
您可以将以下扩展扩展到您需要的任何内容:等等...isValidPhoneNumber
isValidPassword
评论
NSRange
String
utf16.count
characters.count
这是 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
}
评论
最佳解决方案,最佳结果
Swift 4.x
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 的“THE REASONABLE SOLUTION”的新版本,在 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 = "[email protected]"
if str.isEmail {
print("\(str) is a valid e-mail address")
} else {
print("\(str) is not a valid e-mail address")
}
我只是不喜欢在对象上添加一个,因为电子邮件地址是它们固有的(或不是)。因此,根据我的理解,属性比属性更适合。func
String
Bool
func
评论
我改进了@Azik答案。我允许使用指南允许的更多特殊字符,并返回一些额外的边缘情况作为无效。
该小组认为,根据指导方针,这里只允许本地部分是不正确的。请参阅@Anton Gogolev 对这个问题的回答或见下文:._%+-
电子邮件地址的本地部分可以使用以下任何 ASCII 字符:
大写和小写拉丁字母 to 和 to
A
Z
a
z
;digits 设置为
0
9
;特殊字符
!#$%&'*+-/=?^_`{|}~
;dot ,前提是除非引用,否则它不是第一个或最后一个字符,并且除非引用,否则它不会连续出现(例如 是不允许的,但 允许);
.
[email protected]
"John..Doe"@example.com
允许使用空格和字符 限制(它们只允许在带引号的字符串中,如 在下面的段落中描述,此外,反斜杠或 双引号前面必须有反斜杠); 允许评论
"(),:;<>@[\]
在局部部分的两端都有括号;例如: 并且都等价于
john.smith(comment)@example.com
(comment)[email protected]
[email protected]
;
我使用的代码不允许受限制的不合适的特殊字符,但会允许比这里的大多数答案更多的选项。为了谨慎起见,我宁愿更宽松的验证,也不愿犯错误。
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
{
}
在 Swift 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
}
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)
}
}
例
"[email protected]".isValidEmail
返回。。。
true
评论
下面是一个最新的 playground 兼容版本,它使用标准库,因此您不必维护正则表达式:
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 = "[email protected]"
isValid(email: email) // prints 'true'
email.isValidEmail // prints 'true'
评论
mailto://www.google.com
对 a 进行简单的测试,然后发送确认电子邮件。@
.
考虑一下:
- 世界上有一半的人使用非 ASCII 字符。
- 正则表达式缓慢而复杂。顺便说一句,至少检查 char/letter/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"
[email protected]"
试@例子.测试.مثال.آزمایشی"
[email protected]"
[email protected]
- 它错误地将以下内容报告为无效 - 因为它们实际上有效,但可能是用户错误的产物:
a @ b
a@b
相关:
- 电子邮件地址验证应该走多远?
- 在线电子邮件检查器:https://isemail.info/
当电子邮件存在基本问题时,上述大多数正则表达式示例都无法捕获错误。例如
[email protected]
- 连续点[email protected]
- 点后@[email protected]
- 点前@[email protected]
- 以点开头
这是我使用过的一个字符串扩展,它使用具有更严格规则的正则表达式。
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("[email protected]".isValidEmail())
XCTAssertTrue("[email protected]".isValidEmail())
在 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: "[email protected]"))
print(user.validateProperty())
Apple 自己的文档(在 Swift 5.7 中引入)现在提供了一个最小电子邮件验证的示例,并完成了命名组件捕获。RegexBuilder
(复制在这里供后代使用,因为他们有时会改变他们的例子)
let word = OneOrMore(.word)
let emailPattern = Regex {
Capture {
ZeroOrMore {
word
"."
}
word
}
"@"
Capture {
word
OneOrMore {
"."
word
}
}
}
let text = "My email is [email protected]."
if let match = text.firstMatch(of: emailPattern) {
let (wholeMatch, name, domain) = match.output
// wholeMatch is "[email protected]"
// name is "my.name"
// domain is "example.com"
}
尽管这个问题已经有太多的答案,但我觉得这值得分享,因为它:
- 使用最新的 Swift API
- 不会使正则表达式逻辑过于复杂(电子邮件验证的陷阱)
- 直接来自苹果(几乎就像他们知道的那样)
评论
.coffee