2013-03-20 74 views
1

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

+0

我只是看着NSDataDetectors注释部分 - 电子邮件地址不显示为支持的类型 - 难怪它不工作。 – 2013-03-20 14:18:56

+0

@DavidH它不支持 – 2013-03-20 14:25:43

+0

如果您确定,我想将标题更改为“如何检测任意字符串内的电子邮件地址?” – 2013-03-20 14:35:00

回答

5

我在过去做了什么:使用空格

  • 令牌化的输入,例如,不同的令牌(因为大多数其他常见分隔符可能在电子邮件中有效)。然而,如果没有固定正则表达式,这可能不是必要的 - 但不知道如果没有“^”和“$”锚(我添加到网站上显示的内容)它将如何工作。

  • 记住,解决可能采取的形式“‘串’”以及刚刚解决

  • 在每个令牌,寻找“@”,因为它可能是你有它的一个最好的指标电子邮件地址

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

我所做的就是把在文本文件中的正则表达式,所以我不需要逃避它:

^(?!(?:(?:\ 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部分] |( (?:(?:[\ x21 \ x23- \ x27 \ x2A \ x2B \ x2D \ x2F- \ x39 \ x3D \ x2C \ x22 \ x2F) X3F \ x5E- \ x7E] +)|(?:\ X22(:[\ x01- \ X08 \ X0B \ X0C \ x0E- \ x1F的\ X21 \ x23- \ x5B \ x5D- \ 0x7F部分] |(?:? (?:(?:(?!。))。 (?: - [ - z0-9] +(?: - [a-z0-9] +)。){1,126 }){1,}(?:(?:[az] [a-z0-9])|(?:(?: xn - )[a-z0-9] +))(?: - (α:[a-f0-9] +))|(α:[(α: 9] {1,4}){7})|(?:(?!(?:。 [a-f0-9] [:]]){7,})(?:[a-f0-9 ] {1,4} {0,5})::((:: [A-f0-9] {1,4}):?[A-f0-9] {1,4}(?: :[A-f0-9] {1,4}){0,5}))))|(:(?: IPv6的:????(:(:[A-f0-9] {1,4 } {5} :) |((:: [A-f0-9] {1,4}?):?!?((:* [A-f0-9]){5})( ?:[A-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: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 

创建正则表达式:

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:为alterate,不太严格,但速度更快,看到这个question

+0

我执行代码,但得到一个错误:断言失败:(reg &&!错误),... – 2013-03-20 15:04:11

+0

那么,你包括文本文件在你的包? assert只是说你有一个对象,没有错误。实际上,我自己正在做一个演示项目(针对Mac),因为这里还有其他一些复杂性,我想看看更新的正则表达式是否也适用于Apple的正则表达式。完成后会更新我的答案。 – 2013-03-20 17:12:16

+0

是包含文本文件。该模式有价值,但注册号为零。 – 2013-03-21 02:21:10

相关问题