168

验证用户在 iOS 2.0 上输入的电子邮件地址的最简洁方法是什么?

注意:这是一个特定于 iOS 2.0 的历史问题,并且由于它的年龄以及与之相关的其他问题的数量,它不能被淘汰,并且不得更改为“现代”问题。

4

13 回答 13

354

使用正则表达式验证电子邮件地址的答案非常详细地解释了 RFC 5322 中指定的语法对于原始正则表达式来说太复杂了。

我推荐一种真正的解析器方法,例如MKEmailAddress

作为快速正则表达式解决方案,请参阅 DHValidation的此修改:

- (BOOL) validateEmail: (NSString *) candidate {
    NSString *emailRegex =
@"(?:[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])+)\\])"; 
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES[c] %@", emailRegex]; 

    return [emailTest evaluateWithObject:candidate];
}
于 2009-07-19T13:24:03.577 回答
20

阅读 RFC。几乎所有认为自己知道如何解析/清理/验证电子邮件地址的人都是错误的。

https://www.rfc-editor.org/rfc/rfc2822 第 3.4.1 节非常有用。注意

dtext = NO-WS-CTL / ; 非空白控件

                        %d33-90 / ; US-ASCII 的其余部分
                        %d94-126 ; 不包括“[”的字符,
                                        ; “]“, 或者 ”\”

是的,这意味着 +、' 等都是合法的。

于 2009-04-28T22:58:13.617 回答
17

到目前为止,我找到的最好的解决方案(也是我最终选择的解决方案)是将RegexKitLite添加到项目中,该项目可以通过 NSString 类别访问正则表达式。

添加到项目中非常轻松,一旦到位,任何正则表达式电子邮件验证逻辑都将起作用。

于 2009-04-29T14:33:47.393 回答
10

一个好的开始是决定你想接受什么,不想接受什么作为电子邮件地址?

99% 的电子邮件地址如下所示:bob.smith@foo.com 或 fred@bla.edu

但是,拥有这样的电子邮件地址在技术上是合法的:f !#$%&'*+-/=?^_{|}~"ha!"@com

对于顶级域,世界上可能只有少数有效的电子邮件,而且几乎没有人使用大多数其他字符(尤其是引号和反引号),因此您可能想假设这些都是无效的事情。但你应该这样做是有意识的决定。

除此之外,按照 Paul 所说的去做,并尝试将输入匹配到这样的正则表达式:^[A-Z0-9._%+-]+@[A-Z0-9.-]+.[AZ]{ 2,}$

那一个几乎可以匹配每个人的电子邮件地址。

于 2009-04-28T23:04:40.433 回答
7

虽然专注于正则表达式是好的,但这只是第一步,也是必要的一步。还有其他步骤也需要考虑一个好的验证策略。

我头上的两件事是:

  1. DNS 验证以确保域确实存在。

  2. 在 dns 验证后,您还可以选择进行 smtp 验证。向 smtp 服务器发送调用以查看用户是否实际存在。

通过这种方式,您可以捕获各种用户错误并确保它是有效的电子邮件。

于 2009-04-28T23:09:26.320 回答
7

此功能很简单,但更彻底地检查电子邮件地址。例如,根据 RFC2822,电子邮件地址不得连续包含两个句点,例如 firstname..lastname@domain..com

如本函数所示,在正则表达式中使用锚点也很重要。没有锚,以下电子邮件地址被认为是有效的:first;name)lastname@domain.com(blah因为lastname@domain.com部分是有效的,忽略first;name)在开头和(blah在结尾。锚强制正则表达式引擎来验证整个电子邮件。

此函数使用 iOS 2 中不存在的 NSPredicate。不幸的是,它可能无法帮助提问者,但希望能帮助其他人使用更新版本的 iOS。不过,这个函数中的正则表达式仍然可以应用于 iOS 2 中的 RegExKitLite。而对于那些使用 iOS 4 或更高版本的用户,这些正则表达式可以使用 NSRegularExpression 来实现。

- (BOOL)isValidEmail:(NSString *)email
{
    NSString *regex1 = @"\\A[a-z0-9]+([-._][a-z0-9]+)*@([a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,4}\\z";
    NSString *regex2 = @"^(?=.{1,64}@.{4,64}$)(?=.{6,100}$).*";
    NSPredicate *test1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex1];
    NSPredicate *test2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex2];
    return [test1 evaluateWithObject:email] && [test2 evaluateWithObject:email];
}

请参阅在 Objective-C 中使用正则表达式验证电子邮件地址

于 2013-10-15T00:09:40.237 回答
6
NSString *emailString = textField.text; **// storing the entered email in a string.** 
**// Regular expression to checl the email format.** 
NSString *emailReg = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; 
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",emailReg]; 
if (([emailTest evaluateWithObject:emailString] != YES) || [emailStringisEqualToString:@""]) 
{ 
UIAlertView *loginalert = [[UIAlertView alloc] initWithTitle:@" Enter Email in" message:@"abc@example.com format" delegate:self 
cancelButtonTitle:@"OK" otherButtonTitles:nil]; 

enter code here

[loginalert show]; 
[loginalert release]; 
} 
If email is invalid, it will remind the user with an alert box. 
Hope this might be helpful for you all. 
于 2011-12-30T11:44:56.057 回答
4

我发现使用正则表达式可以很好地验证电子邮件地址。

正则表达式的主要缺点当然是可维护性,所以要像以前从未评论过的那样评论。我向你保证,如果你不这样做,你会希望你在几周后回到这个表情时做到这一点。

这是一个很好的来源的链接,http://www.regular-expressions.info/email.html

于 2009-04-28T22:42:20.393 回答
3

挖掘污垢,但我只是偶然发现了SHEmailValidator,它做得非常好,界面也很好。

于 2013-11-15T15:11:22.723 回答
1

许多网站都提供正则表达式,但您最好学习和理解它们,并在官方 RFC 中验证您希望它做的事情是否满足您对电子邮件地址格式的需求。

对于学习 RegEx,解释语言可以是一个很好的简化器和测试平台。Rubular 是基于 Ruby 构建的,但它是一种很好的快速测试和验证方法: http ://www.rubular.com/

除此之外,还可以购买最新版的 O'Reilly 书籍 Mastering Regular Expressions。您需要花时间理解前 3 或 4 章。之后的一切都将建立高度优化的 RegEx 使用方面的专业知识。

通常,一系列更小、更易于管理的 RegEx 更易于维护和调试。

于 2011-03-12T10:36:17.767 回答
0

这是在 Swift 中验证电子邮件的 String 的扩展。

extension String {

    func isValidEmail() -> Bool {
        let stricterFilter = false
        let stricterFilterString = "^[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$"
        let laxString = "^.+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2}[A-Za-z]*$"
        let emailRegex = stricterFilter ? stricterFilterString : laxString
        let emailTest = NSPredicate(format: "SELF MATCHES %@", emailRegex)
        return emailTest.evaluate(with: self)
    }
}

从答案复制到:检查电子邮件地址在 iOS 上是否有效

于 2017-02-16T19:39:12.477 回答
-2

您不应该尝试使用正则表达式来验证电子邮件。随着 TLD 不断变化,您的验证器要么不完整,要么不准确。相反,您应该利用 Apple 的NSDataDetector库来获取字符串并尝试查看是否有任何已知的数据字段(电子邮件、地址、日期等)。Apple 的 SDK 将承担与 TLD 保持同步的繁重工作,您可以借助他们的努力!!:)

另外,如果 iMessage(或任何其他文本字段)认为它不是电子邮件,您是否应该考虑电子邮件?

我将此函数放在一个NSString类别中,因此您要测试的字符串是self.

- (BOOL)isValidEmail {
    // Trim whitespace first
    NSString *trimmedText = [self stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
    if (self && self.length > 0) return NO;

    NSError *error = nil;
    NSDataDetector *dataDetector = [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink error:&error];
    if (!dataDetector) return NO;

    // This string is a valid email only if iOS detects a mailto link out of the full string
    NSArray<NSTextCheckingResult *> *allMatches = [dataDetector matchesInString:trimmedText options:kNilOptions range:NSMakeRange(0, trimmedText.length)];
    if (error) return NO;
    return (allMatches.count == 1 && [[[allMatches.firstObject URL] absoluteString] isEqual:[NSString stringWithFormat:@"mailto:%@", self]]);
}

或作为快速String扩展

extension String {
    func isValidEmail() -> Bool {
        let trimmed = self.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty, let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
            return false
        }
        let allMatches = dataDetector.matches(in: trimmed, options: [], range: NSMakeRange(0, trimmed.characters.count))

        return allMatches.count == 1 && allMatches.first?.url?.absoluteString == "mailto:\(trimmed)"
    }
}
于 2017-09-05T21:12:07.400 回答
-7
// Method Call
NSString *email = @"Your Email string..";

BOOL temp = [self validateEmail:email];

if(temp)
{
// Valid
}
else
{
// Not Valid
}
// Method description

- (BOOL) validateEmail: (NSString *) email {
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    BOOL isValid = [emailTest evaluateWithObject:email];
    return isValid;
}
于 2014-05-19T14:49:14.607 回答