Faz Ya
Faz Ya

Reputation: 1480

Use NSRegularExpression to replace each match with a result of method

I'd like to use enumerateMatchInString to find every abbreviation a call my method ConvertAbbreviation:(NSString *)abbr; to covert that abbreviation and return the full string.

Can someone help me with this? I am getting exceptions when I try the code below. If this is wrong can someone please give me an example of how to modify the original text within the block.

- (NSString *) convertAllAbbreviationsToFullWords:(NSString *) textBlock {

NSRegularExpression *matchAnyPotentialAbv  = [NSRegularExpression regularExpressionWithPattern:@"[a-zA-Z\\.]+\\.\\s" options:0 error:nil];

[matchAnyPotentialAbv 
     enumerateMatchesInString:textBlock
     options:0
     range:NSMakeRange(0, [textBlock length])
     usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) {

        /* on each match, I would like to call convert(match) and
           replace the result with the existing match in my textBlock */ 

        if (++count >= 200) *stop = YES;
     }
     ];
    return textBlock;
}

Upvotes: 2

Views: 2851

Answers (2)

Stuart M
Stuart M

Reputation: 11588

Using NSRegularExpression's -replacementStringForResult:inString:offset:template:] API probably provides a cleaner way to do this, and worked well for me. For a usage guide, see:

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

Upvotes: 2

borrrden
borrrden

Reputation: 33421

You should try a backwards search, otherwise once you modify the text the first time your text ranges are no longer valid.

So, enumerate over all matches like this (you can use this trick to go backwards):

NSArray *results = [matchAnyPotentialAbv matchesInString:textBlock options:kNilOptions range:NSMakeRange(0, textBlock.length)];

for(NSTextCheckingResult *result in [results reverseObjectEnumerator])
{
    //Replace
}

Upvotes: 14

Related Questions