使用NSScanner来parsing一个string

我有一个带有格式标签的string,比如There are {adults} adults, and {children} children 。 我有一个以“成人”和“孩子”为关键词的字典,我需要查找这个值并用这个值replacemacros。 这是完全dynamic的; 键可以是任何东西(所以我不能硬编码一个stringByReplacingString )。

在过去,我只是通过循环一个可变string,然后search字符来完成类似的事情。 删除我已经从源string中search的内容。 看来这正是NSScanner所devise的types,所以我尝试了这个:

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

这个问题是,当我的string以“{”开头,那么扫描器返回NO,而不是YES。 (这是文档所说的应该发生的事情)。 那么我滥用NSScanner吗? scanUpToString不包含正在search的string作为其输出的一部分似乎使其几乎没用…

这可以很容易地改变做我想做的,或者我需要重新写一个可变的string和手动search字符?

使用isAtEnd来确定何时停止。 此外, {}不包含在scanUpToString:的结果中,因此它们将位于下一个string的开头,但循环之后的追加不是必需的,因为即使searchstring为未find。

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