在字符串中替换两个字符的出现

时间:2023-01-12 19:40:34

I have a problem where I need to invert two characters within a string. For example, if my string is "a*b/c" and I want to replace occurrences of * with / and / with *. I want the resulting string to be "a/b*c".

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

Using the method stringByReplacingOccurrenceOfString: doesn't work because I don't want the first round of replacements to affect the second:

使用方法stringByReplacingOccurrenceOfString:不工作,因为我不想第一轮的替换影响第二个:

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

This results in "a*b*c", which is not what I want. Does anybody know an efficient way of accomplishing this?

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

4 个解决方案

#1


4  

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

#2


2  

Use an NSScanner to move through the string and substitute each character as it is found. This way, all substitutions are done in one pass and you're never looking at a position twice.

使用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 now contains the substituted content.

fixedUpString现在包含替换的内容。

As I noted in the comment, this can be generalized very easily to any number of substitutions:

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

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;
    }
}

#3


1  

I had to have a go at this without using the intermediary & character, and though this is certainly more convoluted, this also appears to work:

我必须在不使用中介和字符的情况下进行这一操作,尽管这肯定更复杂,但这似乎也适用:

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;
}

Output:

输出:

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

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

#4


0  

Here's my take on a solution, since I could not find a builtin method that would do what you are looking for.

这是我的一个解决方案,因为我找不到一个可以做你想做的事情的内置方法。

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:@""];
}

#1


4  

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

#2


2  

Use an NSScanner to move through the string and substitute each character as it is found. This way, all substitutions are done in one pass and you're never looking at a position twice.

使用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 now contains the substituted content.

fixedUpString现在包含替换的内容。

As I noted in the comment, this can be generalized very easily to any number of substitutions:

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

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;
    }
}

#3


1  

I had to have a go at this without using the intermediary & character, and though this is certainly more convoluted, this also appears to work:

我必须在不使用中介和字符的情况下进行这一操作,尽管这肯定更复杂,但这似乎也适用:

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;
}

Output:

输出:

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

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

#4


0  

Here's my take on a solution, since I could not find a builtin method that would do what you are looking for.

这是我的一个解决方案,因为我找不到一个可以做你想做的事情的内置方法。

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:@""];
}