简体   繁体   中英

iOS NSString detect link and email using regex

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM