开发者

Replacing numbers in an NSString with Objects from NSArray

In a UITextView users can enter numbers formatted like {{1}} or {{177}}. In a preview field, much like here on SO I'd like to replace that pattern with a value from an NSArray, where the number corresponds to the row in the array.

I have two ideas to solve this:

  1. Count all occurrences with an NSRegularExpression, loop through them and replace them.
  2. Create a word-array out of the NSString and loop through the array, replacing occurrences and put the NSString back together.

Which of those two options is more performant and reliable? Is开发者_StackOverflow社区 there another way?

-- update -- This is the regular expression to find the pattern: @"\\{\\{([1-9]|[1-9][0-9]|[1-9][0-9][0-9])\\}\\}". How can I use this in a loop with an integer to replace the pattern?


Here's an answers using NSRegularExpression:

NSString * input = @"{{83}} fjsdkfjds {{122}}";

NSMutableString * strToMakeReplacements = [[NSMutableString alloc] initWithString:input];

NSError * error = nil;
NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:@"\\{\\{([1-9]|[1-9][0-9]|[1-9][0-9][0-9])\\}\\}" options:NSRegularExpressionCaseInsensitive    error:&error];

NSArray * matches = [regex matchesInString:input options:NSMatchingReportProgress range:NSMakeRange(0, [input length])];

for (int i = [matches count]-1; i>=0 ; i--) {
    NSTextCheckingResult * match = [matches objectAtIndex:i];

    NSRange matchRange = match.range;
    NSString * numString = [input substringWithRange:NSMakeRange(matchRange.location+2, matchRange.length-4)];
    NSInteger num = [numString intValue];

    NSString * replacementValue = [self replacementValueForNum:num]; // write this function yourself

    [strToMakeReplacements replaceCharactersInRange:match.range withString:replacementValue];
}

Note that you need to escape the slashes in your regex, so that it becomes \\{\\{([1-9]|[1-9][0-9]|[1-9][0-9][0-9])\\}\\}


I would use the second approach since it seems more convenient than using regular expressions (although I'm admittedly not very experienced with them).

Given an input string NSString* input I would filter out not numeric characters as follows:

NSCharacterSet* notNumbersSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
NSArray * wholeNumbers = [input componentsSeparatedByCharactersInSet:notNumbersSet];

Now loop through the array of whole numbers:

for( NSString* numString in wholeNumbers ) {
    NSInteger num = [numString intValue];
    // ...
}


A NSRegularExpression approach would be something like this –

NSRegularExpression * expression = [NSRegularExpression regularExpressionWithPattern:@"\\{\\{(\\d+?)\\}\\}"
                                                                             options:0
                                                                               error:nil];
NSMutableString * resultString = [aString mutableCopy];
NSTextCheckingResult * result;
NSUInteger location = 0;

/* Get the first match in the remaining string to search */
while ((result = [expression firstMatchInString:resultString options:0 range:NSMakeRange(location, [resultString length] - location)])) {

    /* Get the index of the array using the capture group 1 i.e. (\\d+?) */
    NSUInteger index = [[resultString substringWithRange:[result rangeAtIndex:1]] integerValue];

    /* Get the string that will replace the match */
    NSString * replacementString = [replacementStrings objectAtIndex:index];

    /* Replace the string */
    [resultString replaceCharactersInRange:result.range withString:replacementString];

    /* Skip to the end of the replaced string */
    location = result.range.location + [replacementString length];
}

Since our replacement strings come from an array I doubt we have a single statement solution to this. Here we find a match, replace it appropriately and then search the rest of the string for a match. We repeat this there are no more results.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜