从NSString中删除html实体-解决方案可在iOS模拟器和设备上运行
我将html存储在从NSString中删除html实体-解决方案可在iOS模拟器和设备上运行,ios,objective-c,nsstring,html-entities,Ios,Objective C,Nsstring,Html Entities,我将html存储在NSString中。我从internet下载并使用NSXMLParser解析它。然而,它似乎与诸如ó,&bdquo,等等。这确实是一个很大的问题,因为它告诉我它失败了,并停止进一步的解析 我在stackoverflow的不同主题中找到了一些很好的解决方案,但他们建议使用NSString+HTML类别或Google Toolbox for Mac(NSString类别使用GTM)。我已经有了使用GTM的项目,这使得在iOS模拟器上运行我的应用程序变得不可能,所以我想避
NSString
中。我从internet下载并使用NSXMLParser
解析它。然而,它似乎与诸如ó代码>,&bdquo代码>,代码>等等。这确实是一个很大的问题,因为它告诉我它失败了,并停止进一步的解析
我在stackoverflow的不同主题中找到了一些很好的解决方案,但他们建议使用NSString+HTML类别或Google Toolbox for Mac(NSString类别使用GTM)。我已经有了使用GTM的项目,这使得在iOS模拟器上运行我的应用程序变得不可能,所以我想避免这种情况。使用NSScanner
编写自己的方法可能是最简单的。注意,实体语法比替换列表稍微复杂一些;即,您需要支持:
- D;其中D是十进制数
- *H*;其中H是十六进制数(大写和小写都可以)
然后,您将需要一个命名实体的映射表(有)
下面是一些代码(在堆栈溢出中编写,未经测试),可以帮助您开始:
static NSDictionary *entityDict;
if (!entityDict)
entityDict = loadEntityMappingTable();
NSScanner *scanner = [NSScanner scannerWithString:myHTMLString];
NSMutableString *result = [NSMutableString string];
[scanner setCharactersToBeSkipped:nil]; // Don’t skip whitespace
while (![scanner isAtEnd]) {
NSString *chunk, *name;
if ([scanner scanUpToString:@"&" intoString:chunk])
[result appendString:chunk];
if ([scanner scanString:@"#" intoString:NULL]) {
unsigned uch;
NSUInteger scanLoc;
BOOL hex = NO;
// This is a numeric reference
if ([scanner scanString:@"x" intoString:NULL]) {
hex = YES;
scanLoc = [scanner scanLocation];
if (![scanner scanHexInt:&uch]) {
// If we fail, show the entire thing in the result string
[result appendString:@"&#x"];
continue;
}
} else {
int ich;
scanLoc = [scanner scanLocation];
if (![scanner scanInt:&ich]) {
// If we fail, show the entire thing
[result appendString:@"&#"];
continue;
}
if (ich < 0) {
// Bad Unicode code point
[result appendString:@"&#"];
[scanner setScanLocation:scanLoc];
continue;
}
uch = (unsigned)ich;
}
// You may also care to prohibit control codes (depending on your application)
// i.e. uch < 0x20 || uch >= 0x7f && uch < 0xa0
if (uch >= 0xd800 && uch <= 0xdfff || uch > 0x10ffff) {
// Bad Unicode code point; show it in the result
[result appendString:hex ? @"&#x" : @"&#"];
[scanner setScanLocation:scanLoc];
continue;
}
if (![scanner scanString:@";" intoString:NULL]) {
// Unterminated; show it in the result
[result appendString:hex ? @"&#x" : @"&#"];
[scanner setScanLocation:scanLoc];
continue;
}
if (uch < 0xffff)
[result appendFormat:@"%C", uch];
else {
unichar lo, hi;
hi = 0xd800 | (uch >> 10);
lo = 0xdc00 | (uch & 0x3ff);
[result appendFormat:@"%C%C", hi, lo];
}
continue;
}
if ([scanner scanUpToString:@";" intoString:&name]) {
NSString *ch;
if (![scanner scanString:@";" intoString:NULL]) {
// Unterminated; show it in the result
[result appendFormat:@"&%@", name];
continue;
}
ch = [entityDict objectForKey:[name lowercaseString]];
if (!ch) {
// Unrecognised; show it in the result
[result appendFormat:@"&%@;", name];
continue;
}
[result appendString:ch];
}
}
静态NSDictionary*entityDict;
if(!entityDict)
entityDict=loadEntityMappingTable();
NSScanner*scanner=[NSScanner scannerWithString:myHTMLString];
NSMutableString*结果=[NSMutableString];
[扫描仪设置字符stobeskiped:nil];//不要跳过空白
而(![scanner isattend]){
NSString*chunk,*name;
if([scanner scanuptString:@“&”intoString:chunk])
[结果追加字符串:块];
if([scanner scanString:@“#”intoString:NULL]){
未签名的uch;
NSU整数扫描定位;
布尔十六进制=否;
//这是一个数字参考
if([scanner scanString:@“x”intoString:NULL]){
十六进制=是;
scanLoc=[扫描仪扫描位置];
如果(![scanner scanHexInt:&uch]){
//如果失败,则在结果字符串中显示整个内容
[结果追加字符串:@“”];
继续;
}
}否则{
int ich;
scanLoc=[扫描仪扫描位置];
如果(![扫描仪扫描:&ich]){
//如果我们失败了,展示整个过程
[结果追加字符串:@“”];
继续;
}
如果(ich<0){
//错误的Unicode代码点
[结果追加字符串:@“”];
[扫描仪设置扫描位置:scanLoc];
继续;
}
uch=(未签名)ich;
}
//您可能还希望禁止控制代码(取决于您的应用)
//即uch<0x20 | | uch>=0x7f&&uch<0xa0
如果(uch>=0xd800&&uch 0x10ffff){
//错误的Unicode代码点;在结果中显示它
[结果追加字符串:十六进制?@“”:@“”];
[扫描仪设置扫描位置:scanLoc];
继续;
}
if(![scanner scanString:@”;“intoString:NULL]){
//未终止;在结果中显示
[结果追加字符串:十六进制?@“”:@“”];
[扫描仪设置扫描位置:scanLoc];
继续;
}
如果(uch<0xffff)
[结果格式:@“%C”,uch];
否则{
尤尼卡罗,你好,;
hi=0xd800 |(uch>>10);
lo=0xdc00 |(uch&0x3ff);
[结果格式:@“%C%C”,高,低];
}
继续;
}
if([scanner scanuptString:@”;“intoString:&name]){
NSString*ch;
if(![scanner scanString:@”;“intoString:NULL]){
//未终止;在结果中显示
[结果格式:@“&%@”,名称];
继续;
}
ch=[entityDict objectForKey:[name lowercaseString]];
如果(!ch){
//未识别;在结果中显示它
[结果附件格式:@“&%@;”,名称];
继续;
}
[结果追加字符串:ch];
}
}
在函数或方法中的某个地方,实现loadEntityMappingTable()
初始化映射字典,它应该可以工作
FWIW,同样的通用方法,使用循环和NSScanner,很容易应用于许多类似的问题,而在脚本语言中,这些问题可以通过正则表达式匹配来解决。到底是什么“使应用程序无法在模拟器上构建”意味着当我在以前的项目中使用GTM时,我无法在模拟器上构建它,但是它在一个设备上工作。问题不清楚,你应该弄清楚你遇到的问题是什么。我编辑了这个问题并澄清了它,希望现在更好。我之前没有注意到ó在我的帖子中显示为ó