在字符串中将两个字符的出现替换为彼此

时间:2013-08-07 18:13:20

标签: objective-c string cocoa nsstring

我有一个问题,我需要在字符串中反转两个字符。例如,如果我的字符串是“a * b / c”,我想用*和/替换*的替换。我希望结果字符串是“a / b * c”。

使用方法stringByReplacingOccurrenceOfString:不起作用,因为我不希望第一轮替换影响第二轮:

string = @"a*b/c";
[string stringByReplacingOccurrencesOfString:@"*" withString:@"/"];
[string stringByReplacingOccurrencesOfString:@"/" withString:@"*"];

这导致“a * b * c”,这不是我想要的。有没有人知道实现这个目标的有效方法?

4 个答案:

答案 0 :(得分:4)

string = @"a*b/c";
[string stringByReplacingOccurrencesOfString:@"*" withString:@"&"];
[string stringByReplacingOccurrencesOfString:@"/" withString:@"*"];
[string stringByReplacingOccurrencesOfString:@"&" withString:@"/"];

答案 1 :(得分:2)

使用NSScanner在字符串中移动并替换找到的每个字符。这样,所有替换都在一次通过中完成,而你永远不会两次查看位置。

NSMutableString * fixedUpString = [NSMutableString string];
NSScanner * scanner = [NSScanner scannerWithString:origString];
NSCharacterSet * subCharacters = [NSCharacterSet characterSetWithCharactersInString:@"*/"];

while( ![scanner isAtEnd] ){

    // Pick up other characters.
    NSString * collector;
    if( [scanner scanUpToCharactersInSet:subCharacters intoString:&collector] ){
        [fixedUpString appendString:collector];
    }

    // This can easily be generalized with a loop over a mapping from
    // found characters to substitutions
    // Check which one we found
    if( [scanner scanString:@"*" intoString:nil] ){

        // Append the appropriate substitution.
        [fixedUpString appendString:@"/"];
    }
    else /* if( [scanner scanString:@"/" intoString:nil] ) */  {
        [fixedUpString appendString:@"*"];
    }
}

fixedUpString现在包含替换内容。

正如我在评论中所指出的,这可以很容易地推广到任意数量的替换:

NSDictionary * substitutions = @{ @"a" : @"z", @"b" : @"y", ... };
NSCharacterSet * keyChars = [NSCharacterSet characterSetWithCharactersInString:[[substitutions allKeys] componentsJoinedByString:@""]];

...

// Check which one we found
for( NSString * keyChar in [substitutions allKeys] ){

    if( [scanner scanString:keyChar intoString:nil ){
        [fixedUpString appendString:substitutions[keyChar]];
        break;
    }
}

答案 2 :(得分:1)

我必须在没有使用中间&字符的情况下进行此操作,虽然这当然更复杂,但这似乎也有效:

int main(int argc, char *argv[])
{

    NSString *s = @"1*2/3*4*5*6*7*8/2";

    NSArray *stars = [s componentsSeparatedByString:@"*"];
    NSMutableArray *slashes = [NSMutableArray array];
    for (NSString *star in stars)
    {
        [slashes addObject:[star componentsSeparatedByString:@"/"]];
    }

    NSMutableArray *newStars = [NSMutableArray array];
    for (NSArray *slash in slashes)
    {
        [newStars addObject:[slash componentsJoinedByString:@"*"]];
    }

    NSString *newString = [newStars componentsJoinedByString:@"/"];

    NSLog(@"%@", newString);

    return 0;
}

输出:

  

1 / * 3/4/5/6/7/8 * 2

答案 3 :(得分:0)

这是我对解决方案的看法,因为我找不到能够满足您需求的内置方法。

NSString *string = @"a*b/c";
NSDictionary *swapings = @{@"*" : @"/", @"/" : @"*"};
NSString *newString = [self swap:swapings inString:string];
NSLog(@"'%@' became '%@'", string, newString);

# ... somewhere in self :

-(NSString *)swap:(NSDictionary *)swapings inString:(NSString *)string {
    NSMutableArray *letters = [NSMutableArray array];
    for (int i = 0; i < [string length]; i++) {
        NSString *letter = [string substringWithRange:NSMakeRange(i, 1)];
        [letters addObject:letter];
    }

    for (int i=0; i<letters.count; i++) {
        NSString *letter = [letters objectAtIndex:i];
        for(NSString *token in [swapings allKeys]) {
            if ([letter isEqualToString:token]) {
                letter = [swapings valueForKey:token];
                break;
            }
        }
        [letters replaceObjectAtIndex:i withObject:letter];
    }

    return [letters componentsJoinedByString:@""];
}