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

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


当前回答

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

其他回答

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

我建议使用它作为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")
}

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

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

let email = "test@example.com"
let rule = EmailValidationPredicate()
let isValidEmail = rule.evaluate(with: email)

在引擎盖后面,它使用RFC 5322 regex (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])+)\\])"

这是@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更适合。

对@和做一个简单的测试。然后发一封确认邮件。

考虑一下:

世界上有一半的人使用非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/