如何检测任意string中的电子邮件地址

我正在使用下面的代码来检测string中的电子邮件。 除了处理纯数字前缀的电子邮件,如“536264846@gmail.com”,它工作正常。 是否有可能克服这个苹果的错误? 任何帮助将不胜感激!

NSString *string = @"536264846@gmail.com"; NSError *error = NULL; NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:&error]; NSArray *matches = [detector matchesInString:string options:0 range:NSMakeRange(0, [string length])]; for (NSTextCheckingResult *match in matches) { if ([match.URL.scheme isEqualToString:@"mailto"]) { NSString *email = [match.URL.absoluteString substringFromIndex:match.URL.scheme.length + 1]; NSLog(@"email :%@",email); }else{ NSLog(@"[match URL] :%@",[match URL]); } } 

编辑 :日志结果是:[匹配URL]: http : //gmail.com

我过去做了什么:

  • 标记input,例如,使用空格分开令牌(因为大多数其他常见分隔符可能在电子邮件中有效)。 然而,如果正则expression式没有被锚定,这可能是没有必要的 – 但不知道如果没有“^”和“$”锚点(我把它添加到网站上显示的内容)它将如何工作。

  • 请记住,地址可能采取“string”的forms以及地址

  • 在每个令牌中,查找“@”,因为它可能是您拥有电子邮件地址的最佳指标

  • 运行这个电子邮件检测器比较网站上显示的正则expression式(我发现在2013年3月21 日标记为#1截至2013年3月21日效果最好)

我所做的是把正则expression式放在一个文本文件中,所以我不需要转义它:

^(?!?(:(:\ 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-? (?: \ x5C [\ x00- \ x7F])) \ x22))(?:。(?: (|:([\ X21 \ x23- \ X27 \ X2A \ X2B \ X2D \ x2F- \ X39 \ X3D \ X3F \ x5E- \ x7E] +):?\ X22(:[\ x01- \ X08 \ (?:\ x5C [\ x00- \ x7F])) \ x22))) @(?:(?:(? ! [^。] {64,})(?:(?:( ?: xn – )?[a-z0-9] +(?: – [a-z0-9] +) 。){1,126 }){1,}(?:(?:[az] [a-z0-9] )|(?:( ?: xn – )[a-z0-9] +))(?: – [a (?:(?:[a-f0-9] {1,4}(?:: [a-f0-9] +) )| {1} {7})|(?:(?!(?:。 [a-f0-9] [:]]){7,})(?:[a-f0-9] {1 ,4}(:: [A-f0-9] {1,4}?){0,5})::(:???[A-f0-9] {1,4}(:: [一-f0-9] {1,4}){0,5}))))|(:( ?: IPv6的:(:(:[A-f0-9] {1,4}(???? :: [A-f0-9] {1,4}){5} 🙂 |(?:?!?。((:* [A-f0-9]){5})?(:一个-f0-9] {1,4} {0,3})::((:: [A-f0-9] {1,4}):?[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}))))$

定义一个伊娃:

 NSRegularExpression *reg 

创build正则expression式:

 NSString *fullPath = [[NSBundle mainBundle] pathForResource:@"EMailRegExp" ofType:@"txt"]; NSString *pattern = [NSString stringWithContentsOfFile:fullPath encoding:NSUTF8StringEncoding error:NULL]; NSError *error = nil; reg = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error]; assert(reg && !error); 

然后写了一个方法来做比较:

 - (BOOL)isValidEmail:(NSString *)string { NSTextCheckingResult *match = [reg firstMatchInString:string options:0 range:NSMakeRange(0, [string length])]; return match ? YES : NO; } 

编辑:我已经把上面的github上的项目

编辑2:为了一个更改,不太严格,但更快,请参阅这个问题的评论部分