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

不要使用扫描仪来解析HTML(也不要使用正则表达式……哦,太痛苦了)*。HTML的全部意义在于,它是一个结构化文档,设计为作为节点或对象的树进行遍历。几乎整个基于DOM(文档对象模型)的行业都是围绕这一点构建的。

只要使用XML解析器就可以了[结构良好的HTML实际上就是XML]。NSXMLDocument(或者——如果您需要事件驱动的——NSXMLParser)将非常有效。

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

这个问题/答案正好描述了这一点,并提供了一个坚实的例子。

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

免责声明:要解析HTML,最好使用像libxml的HTML 4解析器这样的HTML解析器,尤其是处理任意可能格式错误的HTML。无论如何,由于问题是询问如何使用NSParser改进现有代码,因此我提供以下示例。这在大多数情况下都会起作用,但也有一些情况下不会。对于串行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];

最新更新