Objective-C NSString字符替换

时间:2012-03-17 14:26:40

标签: objective-c string character substitution strtr

我有一个NSString类别,我正在努力执行类似于PHP的strtr的字符替换。此方法接受一个字符串并替换fromString中每个字符的每个匹配项,并将其替换为toString中具有相同索引的字符。我有一个工作方法,但它不是非常高效,并希望更快,并能够处理数兆字节的数据。

编辑(为清晰起见):

stringByReplacingOccurrencesOfString:withString:options:range:无效。我必须使用像“ABC”这样的字符串,用“B”代替“A”,用“A”代替“B”,最后用“BAC”代替。 stringByReplacingOccurrencesOfString:withString:options:range:的连续调用会产生类似“AAC”的字符串,这是不正确的。

建议会很棒,示例代码会更好!

代码:

- (NSString *)stringBySubstitutingCharactersFromString:(NSString *)fromString
                                              toString:(NSString *)toString;
{
    NSMutableString *substitutedString = [self mutableCopy];
    NSString *aCharacterString;

    NSUInteger  characterIndex
    ,           stringLength = substitutedString.length;

    for (NSUInteger i = 0; i < stringLength; ++i) {
        aCharacterString = [NSString stringWithFormat: @"%C", [substitutedString characterAtIndex:i]];
        characterIndex = [fromString rangeOfString:aCharacterString].location;

        if (characterIndex == NSNotFound) continue;

        [substitutedString replaceCharactersInRange:NSMakeRange(i, 1)
                                     withString:[NSString stringWithFormat:@"%C", [toString characterAtIndex:characterIndex]]];
    }

    return substitutedString;
}

此代码也是在文本视图中每次更改文本后执行的。它每次都传递整个字符串。我知道有更好的方法,但我不知道怎么做。对此有任何建议肯定会受到赞赏!

1 个答案:

答案 0 :(得分:0)

您可以使用NSRegularExpression进行那种字符串替换,修改可变字符串或创建新的不可变字符串。它将与任何两个字符串一起使用(即使它们不止一个符号),但你需要转义任何在正则表达式中有意义的字符(如\ [ ( . * ? +等)。

模式找到两个带有可选“任何”的子串之一,然后用两个子串替换它们,并保留它们之间的可选字符串。

// These string can be of any length
NSString *firstString = @"Axa";
NSString *secondString = @"By";   
// Escaping of characters used in regular expressions has NOT been done here     
NSString *pattern = [NSString stringWithFormat:@"(%@|%@)(.*?)(%@|%@)", firstString, secondString, firstString, secondString];

NSString *string = @"AxaByCAxaCBy";

NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
                                                                       options:NSRegularExpressionCaseInsensitive
                                                                         error:&error];
if (error) {
    // Insert error handling here...
}

NSString *modifiedString = [regex stringByReplacingMatchesInString:string
                                                           options:0
                                                             range:NSMakeRange(0, [string length])
                                                      withTemplate:@"$3$2$1"];


NSLog(@"Before:\t%@", string);           // AxaByCAxaCBy
NSLog(@"After:  \t%@", modifiedString);  // ByAxaCByCAxa