Searching strings in Xcode using NSScanner and NSRegularExpression

In this post I discuss the different ways in which NSScanner and NSRegularExpression approach searching an NSString in Xcode, and how to make use of the results they provide.

For the entirety of this post and the examples contained in it let's presume we have the following string:


    NSString* string = [NSString stringWithFormat:@"You have %i chances to find me.", 9];


If we use NSScanner then we send the string we wish to search to the NSScanner instance that we are creating:

        
    // First of all create the scanner using the string that you want to scan
    NSScanner* scanner = [NSScanner scannerWithString:string];


before using the instance methods to perform the searches:

  
    // Scanning method to find an integer
    // First we create an integer
    int numberToFind;
    // next we find the number and send it to the integer
    [scanner scanInt:&numberToFind];
  
    // Scanning string up to a set of characters
    //First we need a pointer to a string to send the result to
    NSString* s;
    // next we send our NSScanner instance the method scanUpToCharactersFromSet:CharacterSetWithCharactersInString:intoString:

    [scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"have"]
                   intoString:&s];
    
    NSLog(@"%@ %i", s, numberToFind);


NSRegularExpression takes a different approach. First, it is necessary to create an instance of NSRegularExpression containing the text elements we are looking for:


    // First set up error for checking 
    NSError *error = nil;
    
    // Create regular expression pattern with class method
    NSRegularExpression *regexString = [NSRegularExpression regularExpressionWithPattern:@"h.*" options:NSRegularExpressionSearch error:&error];


 then we can first of all return the number of matches:


// Obtain the number of matches
    NSUInteger numberOfMatches = [regexString numberOfMatchesInString:string
                                                              options:0
                                                                range:NSMakeRange(0, [string length])];
    // Display number of matches in console
    NSLog(@"Number of matches = %d", numberOfMatches);


and then return the text for those matches by first finding the range of the the characters in the string where the matches occur and then asking for the string to return the characters within that range:


     // To return the result
     // first of all obtain the range of the first match
    NSRange rangeOfFirstMatch = [regexString rangeOfFirstMatchInString:string options:0 range:NSMakeRange(0, [string length])];
     // and then ask for a substring with the range of the match - having first checked that there is a result
    if (!NSEqualRanges(rangeOfFirstMatch, NSMakeRange(NSNotFound, 0))) {
        NSString *substringForFirstMatch = [string substringWithRange:rangeOfFirstMatch];
        NSLog(@"Here's your match: %@", substringForFirstMatch);
    }


If we want to display multiple matches then Apple provides the code for this, which I simplify here:


__block NSUInteger count = 0;
    [regexString enumerateMatchesInString:string options:0 range:NSMakeRange(0, [string length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop){

        NSRange rangeOfMatch = [match rangeAtIndex:0];

        NSString *substringForMatches = [string substringWithRange:rangeOfMatch];
        NSLog(@"%@", substringForMatches);
        
        if (++count >= 100) *stop = YES;
    }];}


Hopefully these examples will help you start working with NSScanner and NSRegularExpression classes.


Comments