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

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

注意 : 这是一个特定于 iOS 2.0的历史问题,由于它的年龄以及有多少其他问题与之相关,它不能退役,也不能变成一个“现代”问题。

79693 次浏览

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

正则表达式的主要缺点当然是可维护性,所以像您这样的注释以前从未注释过。我向你保证,如果你不这样做,你会希望你这样做,当你回到表达后,几个星期。

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

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

Https://www.rfc-editor.org/rfc/rfc2822 第3.4.1节非常有用,请注意

dtext           =       NO-WS-CTL /     ; Non white space controls


%d33-90 /       ; The rest of the US-ASCII
%d94-126        ;  characters not including "[",
;  "]", or "\"

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

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

99% 的电子邮件地址都是这样的: bob.smith@foo.com 或 Fred@bla.edu

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

世界上顶级域名的有效邮件可能屈指可数,而且几乎没有人使用其他字符(特别是引号和反勾) ,所以你可能想假设这些都是无效的事情。但你应该有意识地这样做。

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

这个和每个人的邮箱地址都差不多。

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

我脑子里有两件事:

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

  2. 在 dns 验证之后,还可以选择执行 smtp 验证。 将对 smtp 服务器的调用发送到 查看用户是否确实存在。

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

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

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

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

我建议使用像 MKEmailAddress这样的真正的解析器方法。

作为快速正则表达式解决方案,可以看到 确认的这个修改:

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

许多网站都提供了 RegExes,但你最好学习和理解它们,并验证你想要它做的事情是否符合官方 RFC 电子邮件地址格式的需要。

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

除此之外,还可以购买奥赖利的《掌握正则表达式》一书的最新版本。 你会想花时间去理解前3或4章。 之后的一切将是建立高度优化的正则表达式使用的专业知识。

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

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.

这个功能很简单,但检查电子邮件地址更彻底。例如,根据 RFC2822,一个电子邮件地址不能在一行中包含两个句点,比如 firstname.lastname@domain.com

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

该函数使用 iOS2中不存在的 NSPreate。不幸的是,它可能不会帮助要求者,但希望能帮助其他人与新版本的 iOS。不过,这个函数中的正则表达式仍然可以应用于 iOS2中的 RegExKitLite。对于那些使用 iOS4或更高版本的用户,这些正则表达式可以用 NSregarExpression 实现。

- (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 中的正则表达式验证电子邮件地址

挖掘泥土,但我只是偶然发现了 SHEmailValidator它做了一个完美的工作,有一个很好的界面。

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

下面是 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 上是否有效

您不应该尝试使用 regex 来验证电子邮件。随着 TLD 的不断变化,您的验证程序要么是不完整的,要么是不准确的。相反,你应该利用苹果的 NSDataDetector库,它将采取一个字符串,并尝试看看是否有任何已知的数据字段(电子邮件,地址,日期等)。苹果的 SDK 将会完成与顶级域名保持同步的繁重任务,你可以借助他们的努力! !:)

另外,如果 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)"
}
}