NSScanner循环问题

时间:2011-06-12 18:18:50

标签: iphone objective-c nsscanner

我有一个NSScanner对象,可以扫描HTML文档中的段落标记。看起来扫描仪在它找到的第一个结果处停止,但我需要在数组中得到所有结果。

如何改进我的代码以浏览整个文档?

- (NSArray *)getParagraphs:(NSString *) html 
{
    NSScanner *theScanner;
    NSString *text = nil;

    theScanner = [NSScanner scannerWithString: html];

    NSMutableArray*paragraphs = [[NSMutableArray alloc] init];

    // find start of tag
    [theScanner scanUpToString: @"<p>" intoString: NULL];
    if ([theScanner isAtEnd] == NO) {
        NSInteger newLoc = [theScanner scanLocation] + 10;
        [theScanner setScanLocation: newLoc];

        // find end of tag
        [theScanner scanUpToString: @"</p>" intoString: &text];

        [paragraphs addObject:text];
    }

    return text;
}

2 个答案:

答案 0 :(得分:6)

不要使用扫描仪来解析HTML(也不要使用正则表达式......哦,痛苦)*。 HTML的重点在于它是一个结构化文档,旨在作为节点或对象树遍历。几乎所有基于DOM [文档对象模型]的行业都是基于此构建的。

只需使用XML解析器,[结构良好的HTML实际上只是XML]。 NSXMLDocument(或者 - 如果您需要事件驱动 - NSXMLParser)将会很棒。

或者,如果您必须处理格式错误的HTML(即任意服务器污水),请使用正确的HTML解析器。

这个question/answer describes exactly that,有一个很好的例子。

*更不用说解析HTML是业界“解决的问题”。没有必要推出一个新的。

答案 1 :(得分:2)

免责声明:要解析HTML,最好使用像libxml的HTML 4解析器这样的HTML解析器,尤其是处理任意可能格式错误的HTML。无论如何,由于问题是如何使用NSParser来改进现有代码,我提供了以下示例。这在大多数情况下都有效,但有些情况下不会这样。对于seriuos HTML解析,请使用HTML解析器。


迭代直到扫描仪耗尽所有字符:

NSScanner* scanner = [NSScanner scannerWithString:html];
NSMutableArray *paragraphs = [[NSMutableArray alloc] init];
[scanner scanUpToString:@"<p" intoString:nil];
while (![scanner isAtEnd]) {
    [scanner scanUpToString:@">" intoString:nil];
    [scanner scanString:@">" intoString:nil];
    NSString * text = nil;
    [scanner scanUpToString:@"</p>" intoString:&text];
    if (text) { // if html contains empty paragraphs <p></p>, text could be nil
        [paragraphs addObject:text];
    }
    [scanner scanUpToString:@"<p" intoString:nil];
}
...
[paragraphs release];