Using NSScanner to Parse a String

I have a string with formatting tags, for example There are {adults} adults, and {children} children . I have a dictionary that has “adults” and “children” as keys, and I need to find the value and replace the macros with that value. It is fully dynamic; keys can be any (so I can not do hardcode stringByReplacingString ).

In the past, I did similar things before simply looping through a mutable string and looking for characters; removing what i was already looking from the source line when i go. This seems to be exactly what NSScanner is for, so I tried this:

 NSScanner *scanner = [NSScanner scannerWithString:format]; NSString *foundString; scanner.charactersToBeSkipped = nil; NSMutableString *formatedResponse = [NSMutableString string]; while ([scanner scanUpToString:@"{" intoString:&foundString]) { [formatedResponse appendString:[foundString stringByReplacingOccurrencesOfString:@"{" withString:@""]]; //Formatted string contains everything up to the { [scanner scanUpToString:@"}" intoString:&foundString]; NSString *key = [foundString stringByReplacingOccurrencesOfString:@"}" withString:@""]; [formatedResponse appendString:[data objectForKey:key]]; } NSRange range = [format rangeOfString:@"}" options:NSBackwardsSearch]; if (range.location != NSNotFound) { [formatedResponse appendString:[format substringFromIndex:range.location + 1]]; } 

The problem is that when my line starts with "{", the scanner returns NO, not YES. (This is what the documentation says). So am I abusing NSScanner? The fact that scanUpToString does not contain the string you were looking for as part of its output seems to make it almost useless ...

Could this be easily modified to do what I want, or do I need to rewrite with a mutable string and look for characters manually?

+7
source share
1 answer

Use isAtEnd to determine when to stop. In addition, { and } not included in the scanUpToString: result, so they will be at the beginning of the next line, but adding after the loop is not required, because the scanner returns the scanned content even if the search string is not found.

 // Prevent scanner from ignoring whitespace between formats. For example, without this, "{a} {b}" and "{a}{b}" and "{a} //{b}" are all equivalent [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@""]]; while(![scanner isAtEnd]) { if([scanner scanUpToString:@"{" intoString:&foundString]) { [formattedResponse appendString:foundString]; } if(![scanner isAtEnd]) { [scanner scanString:@"{" intoString:nil]; foundString = @""; // scanUpToString doesn't modify foundString if no characters are scanned [scanner scanUpToString:@"}" intoString:&foundString]; [formattedResponse appendString:[data objectForKey:foundString]; [scanner scanString:@"}"]; } } 
+13
source

All Articles