Использование 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]];
}
Проблема в том, что когда моя строка начинается с "{", сканер возвращает НЕТ, а не ДА. (Что и должно быть в документации) Так я неправильно использую NSScanner? Дело в том, что scanUpToString
не включает строку, которую искали как часть ее вывода, кажется, делает ее почти бесполезной...
Может ли это быть легко изменено, чтобы делать то, что я хочу, или мне нужно переписать, используя изменяемую строку и поиск символов вручную?
1 ответ
Использование 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:@"}"];
}
}