使用 NSScanner 解析字符串

发布于 2024-10-25 00:07:04 字数 1334 浏览 7 评论 0原文

我有一个带有格式化标签的字符串,例如 There are {adults} african, and {children} kids。我有一本以“成人”和“儿童”为键的字典,我需要查找该值并用该值替换宏。这是完全动态的;键可以是任何东西(所以我无法对 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 不包含作为其输出的一部分搜索的字符串这一事实似乎使其几乎毫无用处......

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

I have a string with formatting tags in it, such as There are {adults} adults, and {children} children. I have a dictionary which has "adults" and "children" as keys, and I need to look up the value and replace the macros with that value. This is fully dynamic; the keys could be anything (so I can't hardcode a stringByReplacingString).

In the past, I've done similar things before just by looping through a mutable string, and searching for the characters; removing what I've already searched for from the source string as I go. It seems like this is exactly the type of thing NSScanner is designed for, so I tried this:

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

The problem with this is that when my string starts with "{", then the scanner returns NO, instead of YES. (Which is what the documentation says should happen). So am I misusing NSScanner? The fact that scanUpToString doesn't include the string that was being searched for as part of its output seems to make it almost useless...

Can this be easily changed to do what I want, or do I need to re-write using a mutable string and searching for the characters manually?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜`诱少女 2024-11-01 00:07:04

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

Use isAtEnd to determine when to stop. Also, the { and } are not included in the result of scanUpToString:, so they will be at the beginning of the next string, but the append after the loop is not necessary since the scanner will return scanned content even if the search string is not found.

// 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:@"}"];
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文