我有一个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;
}
答案 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];