电子邮件地址的正则表达式

23

有人可以为我展示一个用于电子邮件地址的正则表达式样例,并说明如何在Objective-C中使用吗?

寻找适合以下模式的内容:name@place.something


电子邮件的基本正则表达式为 ^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.(([0-9]{1,3})|([a-zA-Z]{2,3})|(aero|coop|info|museum|name))$ - holex
这里有一个相关的Stackoverflow帖子,其中包含一个参考和示例的答案:https://dev59.com/O3RA5IYBdhLWcg3wvQlh - John F.
3
@holex,这是错误的。我发现的第一个错误是它不允许在@符号左边使用“+”。不要试图进行更正,几乎是不可能的。 - JeremyP
2
@holex 请仔细阅读我的话。实际上最好拿出你的正则表达式和我上一条评论中的有效电子邮件地址进行匹配测试。它不匹配。你的正则表达式中的+符号意味着“至少重复一次”。它们并不意味着“匹配加号”。但是加号在电子邮件地址的本地名称部分是有效的。 - JeremyP
2
@holex 我没有万能的答案。我没有一个,因为使用正则表达式进行电子邮件地址验证是非常困难的。你的回答(好吧,不是回答,而是评论)是错误的。为什么突然说出来就成了罪过? - JeremyP
显示剩余4条评论
4个回答

43

作为特色:http://github.com/benofsky/DHValidation

- (BOOL) validateEmail: (NSString *) candidate {
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; 
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex]; 

    return [emailTest evaluateWithObject:candidate];
}

或者将 http://regexkit.sourceforge.net/RegexKitLite/ 添加到你的项目中,像上面一样自己进行正则表达式匹配。

此外,为了回应检查电子邮件地址是否真实存在的问题,而不仅仅是使用正则表达式来验证,您可以使用一些服务,如:http://verify-email.org/register/levels.html

请注意,此答案没有考虑新的长度为TLD,例如 .online;如果要包括这些,请将最终 {2,4} 更新为 {2,63}


3
苹果公司的 NSRegularExpression 类可以完成相同的任务,不需要使用第三方代码。 - holex
5
我了解正则表达式。看起来是 不了解有效SMTP电子邮件地址的完整语法。我不会提供完整答案,因为这非常难做到。 - JeremyP
5
@holex 去查阅RFC并了解有效电子邮件地址的语法。加号在本地名称部分是允许的。我给出的示例电子邮件地址没有任何问题。它是合法的,但你的正则表达式却说它不是。可以尝试这个链接获取摘要http://en.wikipedia.org/wiki/Email_address - JeremyP
4
我不想打扰,但@JeremyP是正确的:使用正则表达式验证电子邮件地址非常困难且毫无意义。实际上,即使一个语法合法的电子邮件地址也可能不指向实际的邮箱。该页面有关于使用正则表达式的更多信息;向下滚动到名为“官方标准”的部分,可以看到真正的正则表达式:http://www.regular-expressions.info/email.html - mipadi
3
我只是解释了你的评论有误,并不代表我是个喷子。我解释了你的评论哪里出错,这是有用的,因为它让你或提问者可以修复问题。我没有到处指责别人不懂正则表达式,也没有指控任何人是喷子。在回答中解释技术错误比进行人身攻击更有建设性。 - JeremyP
显示剩余15条评论

6
NSString *string= @"my@mail.com her@mail.com him@mail.com";
NSError *error = NULL;
NSRegularExpression *regex = nil;
regex = [NSRegularExpression regularExpressionWithPattern:@"\\w+@[a-zA-Z_]+?\\.[a-zA-Z]{2,6}"
                                                  options:NSRegularExpressionCaseInsensitive
                                                    error:&error];   
NSUInteger numberOfMatches = 0;
numberOfMatches = [regex numberOfMatchesInString:string
                                         options:0
                                           range:NSMakeRange(0, [string length])];
NSLog(@"numberOfMatches is: %lu", numberOfMatches);

当然,还有更多选项。在此处阅读相关内容:这里

我对正则表达式不是很了解,但这个能用于具有复合顶级域名的域名吗?我想我见过像website.com.ca之类的东西?还有带连字符的电子邮件呢? - Albert Renshaw
@AlbertRenshaw 它不会匹配类似于 hi@how.are.you 这样的电子邮件地址,但它可以匹配连字符连接的地址,比如 my-mail@mail.com - Avi Cohen
将顶级域名限制在2到6个字符非常严格。请参阅官方TLD列表:http://www.iana.org/domains/root/db - Toto
@M42 这个问题可以很容易地通过将 {2,6} 替换为 {2,10} 来解决,例如。 - Avi Cohen
当然,但是像 .சிங்கப்பூர்.中國 这样的顶级域名呢? - Toto
对Toto的评论点赞,我们现在有24个字符,需要包括连字符。curl "http://data.iana.org/TLD/tlds-alpha-by-domain.txt" | grep -v '#' | awk '{ if (length($0) > maxLen) { maxLen = length($0); maxString = $0; } } END { print maxLen; print maxString }' - gav

5

因为我在Objective-C中找不到任何严肃的电子邮件正则表达式示例,所以我在这里提供一个:

const char cRegex[] = "^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$";
NSString *emailRegex = [NSString stringWithUTF8String:cRegex];
NSPredicate *emailPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES[c] %@", emailRegex];
BOOL isValid = [emailPredicate evaluateWithObject:email];

这是基于 Michael Rushton 的正则表达式,被 PHP 的 filter_var() 函数使用,根据这个比较,看起来已经足够好了。
祝愉快!

编辑

Swift 4

func isValidEmail(email: String) -> Bool {
    let emailRegex = "^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$"
    return NSPredicate(format: "SELF MATCHES[c] %@", emailRegex).evaluate(with: email)
}

0

无效电子邮件格式的正则表达式:

public static bool IsEmailValid(this string inputStr)
  {
    bool isValid = false;
    if (!string.IsNullOrWhiteSpace(inputStr))
     {
  isValid  = Regex.IsMatch(inputStr, @"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z", 
                                    RegexOptions.IgnoreCase);
       }
    
         return isValid;
    
      }

这不匹配 me@localhost(有效的电子邮件地址),但匹配 ^@a.a(无效的电子邮件地址)。请查看以下网站:顶级域名列表; 有效/无效地址示例; RFC822电子邮件地址的正则表达式 - Toto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接