在iOS 2.0上验证电子邮件地址的最佳做法是什么


167

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

注意:这是一个历史性问题,特定于iOS 2.0,并且由于其年代久远以及与它相关的其他问题数量而定,因此无法淘汰它,并且绝不能将其更改为“现代”问题。


我正在寻找可可溶液。我了解电子邮件的有效性以及有关验证电子邮件的规则。但是,由于RegEx在Cocoa Touch上不易访问,因此我正在寻找可验证的Cocoa Touch解决方案。没有列出有关验证的规则。
Marcus S. Zarra

到目前为止,我发现的最佳代码建议是使用RegExKitLite和正则表达式。幸运的是,它没有听起来那么痛苦。
Marcus S. Zarra 2009年

请参阅以下有关将NSRegularExpression用于不支持os <4.0的应用程序的评论。
beOn 2011年

1
由于这似乎是有关电子邮件地址验证的规范问题,因此随着iOS的成熟,使用改进的答案进行更新是有意义的。考虑到这一点,我添加了一个答案,该答案使用iOS NSDataDetector验证电子邮件地址:stackoverflow.com/a/23547905/257550
备忘录

2
这个问题似乎离题,因为它是关于iOS 2.0的,这在几年前已经过时了。
内森·埃罗

Answers:


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];
}

9
很好,但在OS <3.0上不起作用,因为NSPredicate不可用。
Felixyz

4
真好 每个人都忘记了NSPredicate可以运行正则表达式。
罗格

5
那是一个非常糟糕的正则表达式。例如,它将对使用.museum顶级域的用户失败。请参阅本文:linuxjournal.com/article/9585
Jonny

18
cocoawithlove.com/2009/06/…上有一个更完整的正则表达式,可以用来代替这个简单的正则表达式。
Tomas Andrle

12
这是一个非常天真但宽松的电子邮件正则表达式,它是可可字符串:@"[^@]+@[^.@]+(\\.[^.@]+)+"如果您需要验证电子邮件地址,请向其发送消息,看看是否成功。您永远不会单独使用正则表达式来进行任何级别的准确性验证,因此最好不要因为不必要的严格正则表达式而激怒用户并丢失注册。
Sami Samhuri 2011年

20

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

http://tools.ietf.org/html/rfc2822 第3.4.1节非常有用。注意

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

                        %d33-90 /; 其余的US-ASCII
                        %d94-126; 不包含“ [”的字符,
                                        ; “]“, 要么 ”\”

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


截至2016年5月最新信息:RFC5322,第3.4.1节
-Leanne

17

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

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


5
NSPredicate可以执行RegEx,而无需向项目中添加其他库。
BadPirate

10
这个问题,从2009年4月开始,是NSPredicate在iOS上出现之前。
Marcus S. Zarra

7
同样,当询问此问题时,iOS 2.0中不存在 NSRegularExpression DID
Marcus S. Zarra

9
@Marcus,堆栈溢出的重点不是维护过去解决特定问题的历史记录。就是说,我已经编辑了您的问题,以强调2.0兼容性的角度。
benzado 2011年

2
请阅读标题,该标题适用于不存在Catlan解决方案的iOS 2.0。
Marcus S. Zarra 2012年

10

一个好的开始是确定您是什么,并且您不想接受作为电子邮件地址吗?

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

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

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

除此之外,请执行Paul所说的,并尝试将输入与正则表达式进行匹配,例如:^ [A-Z0-9 ._%+-] + @ [A-Z0-9 .-] +。[AZ] { 2,} $

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


即使此答案写于2009年,其搜索结果仍然很高。我只是想补充一点,这已不再是最新的,并且上面的正则表达式有点限制性。例如,现在您可以拥有4位数或更多的顶级域名
杰克

好点,将其编辑为“至少2位数”。如果您愿意,可以随时进行进一步的编辑。
布兰登·雅伯

7

尽管对正则表达式的关注很好,但这只是第一步和必要步骤。好的验证策略还需要考虑其他步骤。

我头上的两件事是:

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

  2. dns验证后,您也可以选择执行smtp验证。将呼叫发送到smtp服务器,以查看用户是否实际存在。

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


7

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

如在此函数中看到的,在正则表达式中使用锚也很重要。如果没有锚点,则以下电子邮件地址被认为是有效的:first; name)lastname@domain.com(等等,因为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中使用正则表达式验证电子邮件地址


iOS 2.0没有NSPredicate。
Marcus S. Zarra

2
但是,此问题的用途是什么,ios 2的用途是什么。我们拥有的最新操作系统是ios 7.1。你也可以用IOS 6
拉夫·吉拉尼

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. 

4

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

正则表达式的主要缺点当然是可维护性,因此像以前从未评论过的那样进行评论。我向您保证,如果您不这样做,则希望数周后返回表达式时您会这样做。

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


我最近在该页面上实现了倒数第二个,对此我感到非常满意。它适用于简单的user@host.com电子邮件地址,没有全名的引号或括号。对于Web表单验证非常有用,因为人们无论如何都不会键入这种东西。
zombat

2
.museum TLD的贫困人口。
BadPirate

3

挖泥土,但我偶然发现SHEmailValidator,它做得非常好并且界面很好。


这个问题是针对iOS 2.0的,该iOS 2.0没有NSPredicate或该库中正在使用的其他所有主机。
Marcus S. Zarra

1
我知道,但是我在搜索“ ios电子邮件验证”时首先降落在这里。也许将来我会执行相同的搜索并降落在这里,这将为他节省一些时间。
Cyrille

1

许多网站都提供RegExes,但您最好学习和理解它们,并在电子邮件地址的官方RFC中验证您希望它做的事满足您的需求。

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

除此之外,购买O'Reilly最新版的《掌握正则表达式》。您需要花费时间来理解前三章或四章。之后的一切将建立在高度优化的RegEx使用上的专业知识。

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


0

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

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上有效


NSPredicateiOS 2.0上没有此功能
Marcus S. Zarra

-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)"
    }
}

1
这个问题来自八年前。
Marcus S. Zarra

1
但是,如果您是Google validate email objective-c,那么这个问题是第三个结果。互联网上的某些东西不会老化。:-)
Craig Otis

1
请在您发现与验证电子邮件地址相关的每条帖子下方停止向该答案的垃圾邮件链接。评论是为了要求澄清,而不是为您的答案发送垃圾链接。
meagar

顺便说一句,NSDataDetectoriOS 2.0中不存在这个问题。
Marcus S. Zarra

-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;
}

3
该线程/问题是针对 NSPredicateiOS 2的。它没有添加到iOS的3
马库斯S. Zarra

3
我回答是因为您的答案有误。问题是“您如何在iOS Y上执行X操作”,并且使用该版本的iOS上不存在的框架进行了回答。
Marcus S. Zarra 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.