目标C HTML转义/ unescape

想知道是否有一个简单的方法在Objective C中做一个简单的HTML转义/ unescape。我想要的是这样的伪代码:

NSString *string = @"<span>Foo</span>"; [string stringByUnescapingHTML]; 

哪个返回

 <span>Foo</span> 

希望能够避免所有其他的HTML实体,甚至像Ӓ之类的ASCII码。

Cocoa Touch / UIKit中有没有方法可以做到这一点?

此链接包含下面的解决scheme。 Cocoa CF具有CFXMLCreateStringByUnescapingEntitiesfunction,但在iPhone上不可用。

 @interface MREntitiesConverter : NSObject <NSXMLParserDelegate>{ NSMutableString* resultString; } @property (nonatomic, retain) NSMutableString* resultString; - (NSString*)convertEntitiesInString:(NSString*)s; @end @implementation MREntitiesConverter @synthesize resultString; - (id)init { if([super init]) { resultString = [[NSMutableString alloc] init]; } return self; } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)s { [self.resultString appendString:s]; } - (NSString*)convertEntitiesInString:(NSString*)s { if (!s) { NSLog(@"ERROR : Parameter string is nil"); } NSString* xmlStr = [NSString stringWithFormat:@"<d>%@</d>", s]; NSData *data = [xmlStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; NSXMLParser* xmlParse = [[[NSXMLParser alloc] initWithData:data] autorelease]; [xmlParse setDelegate:self]; [xmlParse parse]; return [NSString stringWithFormat:@"%@",resultString]; } - (void)dealloc { [resultString release]; [super dealloc]; } @end 

查看XMLEntities的NSString类别 。 有解码XML实体(包括所有HTML字符引用),编码XML实体,剥离标签和从string中删除换行符和空格的方法:

 - (NSString *)stringByStrippingTags; - (NSString *)stringByDecodingXMLEntities; // Including all HTML character references - (NSString *)stringByEncodingXMLEntities; - (NSString *)stringWithNewLinesAsBRs; - (NSString *)stringByRemovingNewLinesAndWhitespace; 

来自Google Toolbox for Mac的另一个HTML NSString类别
尽pipe名字,这也适用于iOS。

http://google-toolbox-for-mac.googlecode.com/svn/trunk/Foundation/GTMNSString+HTML.h

 /// Get a string where internal characters that are escaped for HTML are unescaped // /// For example, '&amp;' becomes '&' /// Handles &#32; and &#x32; cases as well /// // Returns: // Autoreleased NSString // - (NSString *)gtm_stringByUnescapingFromHTML; 

而且我只能在项目中包含三个文件:头文件,实现文件和GTMDefines.h

这是一个令人难以置信的黑客一起解决scheme,但是如果你想简单地转义一个string,而不必担心分析,这样做:

 -(NSString *)htmlEntityDecode:(NSString *)string { string = [string stringByReplacingOccurrencesOfString:@"&quot;" withString:@"\""]; string = [string stringByReplacingOccurrencesOfString:@"&apos;" withString:@"'"]; string = [string stringByReplacingOccurrencesOfString:@"&lt;" withString:@"<"]; string = [string stringByReplacingOccurrencesOfString:@"&gt;" withString:@">"]; string = [string stringByReplacingOccurrencesOfString:@"&amp;" withString:@"&"]; // Do this last so that, eg @"&amp;lt;" goes to @"&lt;" not @"<" return string; } 

我知道这绝不是优雅的,但它完成了工作。 然后你可以通过调用来解码一个元素:

 string = [self htmlEntityDecode:string]; 

就像我说的那样,它很黑,但是很有效。 如果你想编码一个string,只需反转stringByReplacingOccurencesOfString参数。

在iOS 7中,您可以使用NSAttributedString的能力导入HTML来将HTML实体转换为NSString。

例如:

 @interface NSAttributedString (HTML) + (instancetype)attributedStringWithHTMLString:(NSString *)htmlString; @end @implementation NSAttributedString (HTML) + (instancetype)attributedStringWithHTMLString:(NSString *)htmlString { NSDictionary *options = @{ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute :@(NSUTF8StringEncoding) }; NSData *data = [htmlString dataUsingEncoding:NSUTF8StringEncoding]; return [[NSAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil]; } @end 

然后在你的代码中当你想清理实体时:

 NSString *cleanString = [[NSAttributedString attributedStringWithHTMLString:question.title] string]; 

这可能是最简单的方法,但我不知道它是如何performance的。 你可能应该非常确定你的“清理”内容不包含任何<img>标签或类似的东西,因为这个方法将在HTML到NSAttributedString转换过程中下载这些图像。 🙂

这是一个解决scheme,通过使所有的字符(通过使所有的HTML编码的实体为他们的Unicode值)…用于我的需要(确保一个string来自用户,但放置在一个Web视图不能有任何XSS攻击):

接口:

 @interface NSString (escape) - (NSString*)stringByEncodingHTMLEntities; @end 

执行:

 @implementation NSString (escape) - (NSString*)stringByEncodingHTMLEntities { // Rather then mapping each individual entity and checking if it needs to be replaced, we simply replace every character with the hex entity NSMutableString *resultString = [NSMutableString string]; for(int pos = 0; pos<[self length]; pos++) [resultString appendFormat:@"&#x%x;",[self characterAtIndex:pos]]; return [NSString stringWithString:resultString]; } @end 

用法示例:

 UIWebView *webView = [[UIWebView alloc] init]; NSString *userInput = @"<script>alert('This is an XSS ATTACK!');</script>"; NSString *safeInput = [userInput stringByEncodingHTMLEntities]; [webView loadHTMLString:safeInput baseURL:nil]; 

你的里程会有所不同。

编码和解码HTML或XMLstring的侵入性最小,最轻量级的方法是使用GTMNSStringHTMLAdditions CocoaPod 。

这简直就是Google Toolbox for Mac NSString类别GTMNSString+HTML ,剥夺了对GTMDefines.h的依赖。 所以你只需要添加一个.h和一个。你就可以走了。

例:

 #import "GTMNSString+HTML.h" // Encoding a string with XML / HTML elements NSString *stringToEncode = @"<TheBeat>Goes On</TheBeat>"; NSString *encodedString = [stringToEncode gtm_stringByEscapingForHTML]; // encodedString looks like this now: // &lt;TheBeat&gt;Goes On&lt;/TheBeat&gt; // Decoding a string with XML / HTML encoded elements NSString *stringToDecode = @"&lt;TheBeat&gt;Goes On&lt;/TheBeat&gt;"; NSString *decodedString = [stringToDecode gtm_stringByUnescapingFromHTML]; // decodedString looks like this now: // <TheBeat>Goes On</TheBeat> 

这是一个易于使用的NSString类别实现:

这是远远没有完成,但你可以从这里添加一些缺less的实体: http : //code.google.com/p/statz/source/browse/trunk/NSString%2BHTML.m

用法:

 #import "NSString+HTML.h" NSString *raw = [NSString stringWithFormat:@"<div></div>"]; NSString *escaped = [raw htmlEscapedString]; 

上面的MREntitiesConverter是一个HTML剥离器,而不是编码器。

如果您需要编码器,请转到此处: 为XML / HTML编码NSString

MREntitiesConverter不能用于转义格式错误的XML。 它将在一个简单的URL上失败:

http://www.google.com/search?client=safari&rls=en&q=fail&ie=UTF-8&oe=UTF-8

如果你需要生成一个文字你可能会考虑使用这样的工具:

http://www.freeformatter.com/java-dotnet-escape.html#ad-output

为你完成工作。

另请参阅此答案 。

这个最简单的解决scheme是创build一个类别如下:

这里是类别的头文件:

 #import <Foundation/Foundation.h> @interface NSString (URLEncoding) -(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding; @end 

这是实现:

 #import "NSString+URLEncoding.h" @implementation NSString (URLEncoding) -(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding { return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", CFStringConvertNSStringEncodingToEncoding(encoding)); } @end 

现在我们可以简单地做到这一点:

 NSString *raw = @"hell & brimstone + earthly/delight"; NSString *url = [NSString stringWithFormat:@"http://example.com/example?param=%@", [raw urlEncodeUsingEncoding:NSUTF8Encoding]]; NSLog(url); 

这个答案的信贷进入下面的网站: –

 http://madebymany.com/blog/url-encoding-an-nsstring-on-ios 

为什么不只是使用?

 NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; NSString *result = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; return result; 

Noob的问题,但在我的情况下,它的作品…

这是几年前我发布的一个旧的答案。 我的目的不是要提供一个“好”和“可敬”的解决scheme,而是一个在某些情况下可能有用的“黑客”解决scheme。 请不要使用这个解决scheme,除非没有其他的工作。

实际上,在许多情况下,其他答案并不是因为UIWebView正在完成所有工作,所以它工作得很好。 你甚至可以注入一些JavaScript(这可能是危险的和/或有用的)。 表演应该是可怕的,但实际上并不坏。

还有另外一个解决scheme需要提及。 只要创build一个UIWebView ,加载编码的string,并返回文本。 它转义标签“<>”,也解码所有的HTML实体(例如“&GT;”),它可能工作在别人不这样做(例如使用西里尔)。 我不认为这是最好的解决scheme,但如果上述解决scheme不起作用,这可能是有用的。

这是一个使用ARC的小例子:

 @interface YourClass() <UIWebViewDelegate> @property UIWebView *webView; @end @implementation YourClass - (void)someMethodWhereYouGetTheHtmlString:(NSString *)htmlString { self.webView = [[UIWebView alloc] init]; NSString *htmlString = [NSString stringWithFormat:@"<html><body>%@</body></html>", self.description]; [self.webView loadHTMLString:htmlString baseURL:nil]; self.webView.delegate = self; } - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { self.webView = nil; } - (void)webViewDidFinishLoad:(UIWebView *)webView { self.webView = nil; NSString *escapedString = [self.webView stringByEvaluatingJavaScriptFromString:@"document.body.textContent;"]; } - (void)webViewDidStartLoad:(UIWebView *)webView { // Do Nothing } @end