6

我有一个带有格式标签的字符串,例如There are {adults} adults, and {children} children. 我有一本以“成人”和“儿童”为键的字典,我需要查找该值并用该值替换宏。这是完全动态的;键可以是任何东西(所以我不能硬编码 a 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似乎使它几乎没用......

这可以很容易地更改为我想要的,还是我需要使用可变字符串重写并手动搜索字符?

4

1 回答 1

12

用于isAtEnd确定何时停止。此外,{and}不包含在 的结果中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:@"}"];
    }
}
于 2011-03-22T19:31:35.313 回答