Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you use NSRegularExpression's replacementStringForResult:inString:offset:template:

I have a series of characters that I want to match with a regular expression, and replace them with specific strings depending on what they are.

Example:

In => "This is the input string where i want to replace 1 2 & 3"

Out => "This is the input string where i want to replace ONE TWO & THREE"

I currently do this by splitting the string using spaces as the separator, and parsing each string individually, incrementally rebuilding the string. I feel this is ugly, and lacking imagination, and kinda slow.

According the Apple documentation I should be able to do this using the replacementStringForResult:inString:offset:template: method. However I can't seem to understand how to use it correctly.

like image 539
Jonathan Avatar asked Jun 03 '11 01:06

Jonathan


1 Answers

You can use the method within a for in loop using matchesInString:options:range:, which returns an array of matches as NSTextCheckingResults:

NSError* error = NULL;
NSRegularExpression* regex = [NSRegularExpression 
                              regularExpressionWithPattern:@"\\b[1-3]\\b"
                              options:NSRegularExpressionCaseInsensitive
                              error:&error]; 

NSString* yourString = @"This is the input string where i want to replace 1 2 & 3";

NSMutableString* mutableString = [yourString mutableCopy];
NSInteger offset = 0; // keeps track of range changes in the string
                      // due to replacements.
for (NSTextCheckingResult* result in [regex matchesInString:yourString 
                                                    options:0 
                                                      range:NSMakeRange(0, [yourString length])]) {

    NSRange resultRange = [result range];   
    resultRange.location += offset; // resultRange.location is updated 
                                    // based on the offset updated below

    // implement your own replace functionality using
    // replacementStringForResult:inString:offset:template:
    // note that in the template $0 is replaced by the match
    NSString* match = [regex replacementStringForResult:result 
                                               inString:mutableString 
                                                 offset:offset 
                                               template:@"$0"];
    NSString* replacement;
    if ([match isEqualToString:@"1"]) {
        replacement = @"ONE";
    } else if ([match isEqualToString:@"2"]) {
        replacement = @"TWO";
    } else if ([match isEqualToString:@"3"]) {
        replacement = @"THREE";
    }

    // make the replacement
    [mutableString replaceCharactersInRange:resultRange withString:replacement];

    // update the offset based on the replacement
    offset += ([replacement length] - resultRange.length);
}

NSLog(@"mutableString: %@", mutableString); // mutableString: This is the input string where i want to replace ONE TWO & THREE
like image 176
Dan Sandland Avatar answered Oct 05 '22 23:10

Dan Sandland