使用NSScanner解析字符串

Gen*_*ari 6 objective-c nsstring ios nsscanner

我有一个带有格式标签的字符串,例如There are {adults} adults, and {children} children.我有一个字典,其中"成人"和"孩子"作为键,我需要查找值并用该值替换宏.这是完全动态的; 键可以是任何东西(所以我不能硬编码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]];
}
Run Code Online (Sandbox Code Playgroud)

这个问题是,当我的字符串以"{"开头时,扫描仪返回NO,而不是YES.(这是文档所说的应该发生的事情).我是否滥用NSScanner?事实上,scanUpToString不包括作为其输出的一部分被搜索的字符串似乎使它几乎无用......

这可以轻松更改为我想要的,或者我是否需要使用可变字符串重写并手动搜索字符?

ugh*_*fhw 12

使用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:@"}"];
    }
}
Run Code Online (Sandbox Code Playgroud)