html中如何显示纯文本,从Html中取出纯文本

本文介绍了在iOS开发中从HTML字符串提取纯文本的三种方案:使用NSAttributedString的NSHTMLTextDocumentType,谷歌的NSString+HTML工具箱,以及自定义过滤HTML标签的方法。分别讨论了它们的性能、兼容性、遗留问题及其解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求来源

从后台返回的数据是一个数组,每个数组元素是html字符串,可以显示在一个UIWebView中。

在显示这个html字符串的详情页面的上一级是一个列表,展示标题和内容简介。但是,后台返回的数据中并没有简介字段。

万能的交互和技术一商量,接口不改,让iOS和Android客户端从“html字符串”中抽出具体的内容,当成简介。列表就显示3行,多余的用...来表示。霸道而虚弱的后台,就算吐槽也没用。

方案一:NSAttributedString

项目最低支持iOS7,所以NSAttributedString可以使用,其中有一个option叫做NSHTMLTextDocumentType,就是专门用来从“html字符串”抽取纯文本的。iOS UILabel显示HTML文本

这种API比较难用,所以这里要记一下,希望苹果以后能提供好用一点的API

NSString *htmlString = @"

Some html string \n This is some text! ";

NSAttributedString *attrStr = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];

UILabel *myLabel = [[UILabel alloc] initWithFrame:self.view.bounds];

myLabel.attributedText = attrStr;

[self.view addSubview:myLabel];

从功能上来说,没有问题。不过,我们的应用场景是表格,而NSAttributedString是有比较严重的性能问题,表格会很卡,甚至还会崩溃。NSHTMLTextDocumentType is Slow

方案二:NSString+HTML

谷歌在很久之前就出过一个toolbox,里面有从“html字符串”抽取内容的函数。- (NSString *)gtm_stringByEscapingForHTML;就可以了。

实际用了一下,性能问题是解决了,不过有两个障碍需要解决:

这个库比较老,而且还是MRC的

大多数的html的标签是可以去掉的,但是还有残留,有些html标签去不掉,功能有问题,具体的原因,暂时还不清楚。

怎么解决

现在的工程是ARC的,引入MRC的源文件,会编译不过。所以要加编译选项,进行ARC和MRC的混编。对于需要MRC的源文件,添加-fno-objc-arc标记。Xcode中实现ARC和MRC混编

对于标签残留的问题,已经有人经过深入的研究,并且给出了解决方法- (NSString *)stringByConvertingHTMLToPlainText; 函数就可以了。

发现的坑

htmlUnescapes是一个全局的字典,通过键值对的方式将html的一些特殊标签替换为本地的表示方式。比如,将
替换为\n;但是这里却忘了将
替换为\n;

- (NSString *)stringByConvertingHTMLToPlainText;函数实现的扫描比对部分还是有问题的。比如输入是“abcd(abc), 1821”,结果变成了“abcd(abc), ”,数字“1821”被替换成了“”空字符。具体的原因和解决方法还没有找到。

这个第三方库的star数目有二百多,是在gitHub上输入HTML和Object-C关键字出现的star数目最多的一个。不过最后的更新还是在4年前,Goggle那个工具箱也是老掉牙了,还是MRC的。只是现在没有找到更好的,暂时还能用。

方案三:自己写

如果是将html中的<>标签全部去除,那么实现就相对简单,可以自己实现。<>标签没有嵌套,这是很重要的一个特性。将<>标签里的内容,包括<>本身都替换为空字符串“”就可以了。IOS去掉字符串中HTML标签的方法

- (NSString *)filterHTML:(NSString *)html {

NSScanner *scanner = [NSScanner scannerWithString:html];

NSString *text = nil;

while(![scanner isAtEnd]) {

//找到标签的起始位置

[scanner scanUpToString:@"

//找到标签的结束位置

[scanner scanUpToString:@">" intoString:&text];

//替换字符

html = [html stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@>",text] withString:@""];

}

return html;

}

如果需求复杂一点,比如

要保留,不能简单的去掉,而是要替换为\n那么实现就复杂一点了。估计要在上面的代码中加入额外的判断了

如果要考虑全html那些特殊标签,那么估计代码就更复杂一点了。上面用的第三方库,基本的思路也是这个,考虑得比较全面,代码比较多。