如何检测任意字符串中的电子邮件地址

时间:2013-03-20 13:36:01

标签: ios email nsdatadetector

我正在使用以下代码检测字符串中的电子邮件。除了处理具有纯数字前缀的电子邮件,例如“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]);
    }

}

修改: 日志结果为:[匹配网址]:http://gmail.com

1 个答案:

答案 0 :(得分:5)

我过去做过的事情:

  • 将输入标记化,例如,使用空格分隔标记(因为大多数其他常见分隔符在电子邮件中可能有效)。但是,如果正则表达式没有锚定,则可能没有必要这样做 - 但不确定如果没有“^”和“$”锚点(我添加到网站上显示的内容)它将如何工作。

  • 请注意,地址可能采用“字符串”形式以及地址

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

  • 通过this Email Detector comparison site上显示的正则表达式运行令牌(我在测试中发现截至2013年3月21日的one marked #1效果最佳)

我所做的是将正则表达式放在文本文件中,所以我不需要转义它:

  ?!??

^((:(:\ 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- \ 0x7F部分] |(?:\ x5C [\ x00- \ 0x7F部分))的 \ X22))( ?:(:(:[\ X21 \ x23- \ X27 \ X2A \ X2B \ X2D \ x2F- \ X39 \ X3D \ X3F \ x5E- \ x7E] +)|(:????\ X22(:[ \ x01- \ X08 \ X0B \ X0C \ x0E- \ x1F的\ X21 \ x23- \ x5B \ x5D- \ 0x7F部分] |(?:\ x5C [\ x00- \ 0x7F部分])) \ X22)) ) @(:(:???!????( [^] {64,})(:( :( ?: XN - )[A-Z0-9] + (?: - [A-Z0-9] +)){1126}){1,}(:(:[AZ] [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})| )(:(:( ?: 25 [0-5]。):([1-9] [0-9]?)|(?:2 [0-4] [0-9])| (:1 [0-9] {2}?)|(?:?[1-9] [0-9]))){3}))))$

定义了一个伊娃:

NSRegularExpression *reg

创建正则表达式:

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

编辑:我已将上述内容变为project on github

EDIT2:对于更改,不那么严谨但更快,请参阅此question的评论部分

相关问题