我正在使用以下代码来检测字符串中的电子邮件。除了处理具有纯数字前缀的电子邮件(例如“[email protected]”)外,它都可以正常工作。有可能克服苹果的这个臭虫吗?任何帮助将不胜感激!

NSString *string = @"[email protected]";
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

最佳答案

我过去所做的事情:

  • 将输入标记化,例如,使用空格分隔标记(因为大多数其他通用分隔符在电子邮件中可能是有效的)。但是,如果未锚定正则表达式,则可能没有必要-但不确定在没有“^”和“$”锚(我将其添加到网站上显示的锚)的情况下它将如何工作。
  • 请注意,地址可以采用““字符串”“的形式,也可以采用地址
  • 在每个 token 中的
  • 中,查找“@”,因为这可能是表明其电子邮件地址为
  • 的最佳指示
  • 通过this Email Detector comparison site上显示的正则表达式运行 token (我在测试中发现,截至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- \ 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,}(?:(?:[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})|(?:[1-9]?[0-9]))(?:。(?:(? :25 [0-5])|(?? 2 [0-4] [0-9])|(?:1 [0-9] {2})|(?:[1-9]?[0-9]))){3})))))) )$

    定义一个ivar:
    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的注释部分

  • 10-08 07:44