我有一个字符串,里面有格式化标签,比如There are {adults} adults, and {children} children
。我有一本以“成人”和“ child ”为键的字典,我需要查找值并用该值替换宏。这是完全动态的;键可以是任何东西(所以我不能硬编码 stringByReplacingString
)。
在过去,我只是通过遍历可变字符串并搜索字符来完成类似的事情;删除我已经从源字符串中搜索过的内容。看起来这正是 NSScanner 的设计目标,所以我尝试了这个:
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]];
}
问题是当我的字符串以“{”开头时,扫描器返回 NO,而不是 YES。 (这是文档说应该发生的)。那我是在滥用 NSScanner 吗? scanUpToString
不包含正在搜索的字符串作为其输出的一部分这一事实似乎使它几乎毫无用处......
这是否可以轻松更改以执行我想要的操作,或者我是否需要使用可变字符串重新编写并手动搜索字符?
最佳答案
使用 isAtEnd
确定何时停止。此外,{
和 }
不包含在 scanUpToString:
的结果中,因此它们将位于下一个字符串的开头,但是循环后的附加不是必需的,因为即使找不到搜索字符串,扫描器也会返回扫描的内容。
// 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:@"}"];
}
}
关于objective-c - 使用 NSScanner 解析字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5396134/