Objective-C中的正则表达式:如何用动态模板替换匹配?

Aur*_*bon 1 regex objective-c ios

我的意见就像"Hi {{username}}",即.包含要替换的关键字的字符串.但是,输入非常小(大约10个关键字和1000个字符),并且我有一百万个可能的关键字存储在哈希表数据结构中,每个关联都与其替换相关联.

因此,我不想迭代关键字列表并尝试替换输入中的每一个,这是出于明显的性能原因.我更喜欢通过查找正则表达式模式在输入字符上只迭代一次"\{\{.+?\}\}".

在Java中,我使用Matcher.appendReplacementMatcher.appendTail方法来做到这一点.但我找不到类似的API NSRegularExpression.

private String replaceKeywords(String input)
{        
    Matcher m = Pattern.compile("\\{\\{(.+?)\\}\\}").matcher(input);
    StringBuffer sb = new StringBuffer();

    while (m.find())
    {
        String replacement = getReplacement(m.group(1));
        m.appendReplacement(sb, replacement);
    }

    m.appendTail(sb);
    return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)

我自己被迫实施这样的API,还是我错过了什么?

Mar*_*n R 5

你可以用NSRegularExpression:

NSString *original = @"Hi {{username}} ... {{foo}}";
NSDictionary *replacementDict = @{@"username": @"Peter", @"foo": @"bar"};

NSString *pattern = @"\\{\\{(.+?)\\}\\}";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
                                       options:0
                                     error:NULL];

NSMutableString *replaced = [original mutableCopy];
__block NSInteger offset = 0;
[regex enumerateMatchesInString:original
            options:0
              range:NSMakeRange(0, original.length)
             usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
    NSRange range1 = [result rangeAtIndex:1]; // range of the matched subgroup
    NSString *key = [original substringWithRange:range1];
    NSString *value = replacementDict[key];
    if (value != nil) {
        NSRange range = [result range]; // range of the matched pattern
        // Update location according to previous modifications:
        range.location += offset;
        [replaced replaceCharactersInRange:range withString:value];
        offset += value.length - range.length; // Update offset
    }
}];
NSLog(@"%@", replaced);
// Output: Hi Peter ... bar
Run Code Online (Sandbox Code Playgroud)