4

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

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

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

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

4

4 回答 4

4
string = @"a*b/c";
[string stringByReplacingOccurrencesOfString:@"*" withString:@"&"];
[string stringByReplacingOccurrencesOfString:@"/" withString:@"*"];
[string stringByReplacingOccurrencesOfString:@"&" withString:@"/"];
于 2013-08-07T18:15:26.670 回答
2

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

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;
    }
}
于 2013-08-07T18:26:39.377 回答
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/2*3/4/5/6/7/8*2

于 2013-08-07T18:26:43.593 回答
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:@""];
}
于 2013-08-07T22:08:24.863 回答