有人知道如何在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;
}
}
但我无法翻译成斯威夫特。
我会使用npredicate:
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
}
这里有很多正确答案,但许多“正则表达式”是不完整的,可能会发生像“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
}
}
}
我会使用npredicate:
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等语言中没有转义。
在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())