2

我有一个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;
}
4

2 回答 2

6

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

只需使用 XML 解析器,因为 [结构良好的 HTML 实际上只是 XML]。 NSXMLDocument(或者——如果你需要事件驱动—— NSXMLParser)将很有效。

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

这个问题/答案通过一个可靠的例子准确地描述了这一点。

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

于 2011-06-12T20:02:02.517 回答
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];
于 2011-06-12T18:28:04.917 回答