1

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

4

1 回答 1

5

我过去做了什么:

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

  • 请记住,地址可能采用“字符串”的形式,也可能只是地址

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

  • 通过此电子邮件检测器比较站点上显示的正则表达式运行令牌(我在测试中发现,截至 2013 年 3 月 21日标记为 #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;
}

编辑:我已经把上面的变成了github上的一个项目

EDIT2:对于一个替代的、不那么严格但更快的方法,请参阅这个问题的评论部分

于 2013-03-20T14:32:11.830 回答