简体   繁体   中英

Replace using regular expression with replacement function

In objective-c (for ios) I want to achieve the same as I can in AS3:

var test:String = "Abba";
var reg:RegExp = /(a)|(b)/g;

var replacement:Function = function (...args):String
{
    var $1:String = args[1];//matched 'a'
    var $2:String = args[2];//matched 'b'
    if($1)
    {
        //replace a with -
        return "-";
    }
    if ($2)
    {
        //replace b with +
        return "+";
    }
    return null;
}

var result:String = test.replace(reg, replacement);//A++-
trace(test, result);//Abba A++-

In other words I would like to have ability to identify which capturing group was matched and replace it accordingly, I'm looking for examples on enumerateMatchesInString: but can't find anything that can solve my problem.

enumerateMatchesInString: calls a block with an NSTextCheckingResult for each match, and rangeAtIndex:idx gives the range of a captured subgroup:

NSString *string = @"Abba";
NSString *pattern = @"(a)|(b)";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
                                       options:0
                                     error:NULL];

NSMutableString *newString = [string mutableCopy];
[regex enumerateMatchesInString:string options:0 range:NSMakeRange(0, [string length])
             usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
                 NSRange r1 = [result rangeAtIndex:1];
                 if (r1.location != NSNotFound) {
                     [newString replaceCharactersInRange:r1 withString:@"-"];
                 }
                 NSRange r2 = [result rangeAtIndex:2];
                 if (r2.location != NSNotFound) {
                     [newString replaceCharactersInRange:r2 withString:@"+"];
                 }
             }];
NSLog(@"%@", newString);
// Output: A++-

If the replacement strings have not the same length as the original strings, then it gets slightly more complicated, because you have to keep track of the length changes in the resulting string:

NSMutableString *newString = [string mutableCopy];
__block int offset = 0;
[regex enumerateMatchesInString:string options:0 range:NSMakeRange(0, [string length])
             usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
                 NSRange r1 = [result rangeAtIndex:1];
                 if (r1.location != NSNotFound) {
                     r1.location += offset;
                     NSString *repl = @"---";
                     [newString replaceCharactersInRange:r1 withString:repl];
                     offset += [repl length] - r1.length;
                 }
                 NSRange r2 = [result rangeAtIndex:2];
                 if (r2.location != NSNotFound) {
                     r2.location += offset;
                     NSString *repl = @"++";
                     [newString replaceCharactersInRange:r2 withString:repl];
                     offset += [repl length] - r2.length;
                 }
             }];
NSLog(@"%@", newString);
// Output: A++++---

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