I sort of already have an answer to my question but I want to know if there is a better way of doing this.
Currently I am using the following to detect links and emails in a NSString
:
NSString *teststring = @"this has a link http://google.com/232&q=23%67fg and an email admin007.info@yahoo.com in the sentence";
NSString *linkregex = @"(http|ftp|https)://([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?";
NSPredicate *linkpredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", linkregex];
NSString *emailregex = @"^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$";
NSPredicate *emailpredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailregex];
NSArray *arrayofwords = [teststring componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
arrayofwords = [arrayofwords filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF != ''"]];
for (NSString *word in arrayofwords) {
if ([linkpredicate evaluateWithObject: word]){
NSLog(@"Matches link regex: %@",word);
}
if ([emailpredicate evaluateWithObject: word]){
NSLog(@"Matches email regex: %@",word);
}
}
This works and prints out:
Matches link regex: http://google.com/232&q=23%67fg
Matches email regex: admin007.info@yahoo.com
I want to know if there is any way to avoid the creation of the temporary array of words arrayofwords
? Is it possible for the regex to find all matches of the regex in an entire sentence? The temporary array of words way can cause slowness if I have very very long sentences (reading an entire file as a NSString
). I am not sure if this a "regex" question or more of an iOS question?
A user posted a better solution using NSDataDetector
to my problem but seems like they deleted the solution. I tested it and it works perfectly in my scenario so I am posting this here. If they post it again, please comment below and I will accept their solution.
[self detectType:@"this has a link http://google.com/232&q=23%67fg and an email admin007.info@yahoo.com in the sentence"];
-(void)detectType:(NSString*)stringToUse{
NSError *error;
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes: NSTextCheckingTypeLink error:&error];
if (!error && detector) {
[detector enumerateMatchesInString:stringToUse options:0 range:NSMakeRange(0, stringToUse.length) usingBlock:^(NSTextCheckingResult * __nullable result, NSMatchingFlags flags, BOOL *stop){
NSString *type;
NSString *matched = [stringToUse substringWithRange:result.range];
// Type checking can be eliminated since it is used for logging only.
if (result.resultType==NSTextCheckingTypeLink) {
if ([matched rangeOfString:@"@"].length) {
type = @"Email";
}else{
type = @"Link";
}
} else {
type = @"Unknown";
}
NSLog(@"Matched %@: %@",type,matched);
}];
} else {
NSLog(@"%@",error.description);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.