有人知道如何在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;
}
}
但我无法翻译成斯威夫特。
对@和做一个简单的测试。然后发一封确认邮件。
考虑一下:
世界上有一半的人使用非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
相关:
电子邮件地址验证应该走多远?
在线电子邮件检查:https://isemail.info/
创建简单的扩展:
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等…
或者你可以扩展可选文本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
}
}
对于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
}
}
}
这是@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 = "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更适合。