108

有几种不同的方法可以HTML tagsNSStringin 中删除Cocoa

一种方法是将字符串渲染成一个NSAttributedString,然后抓取渲染的文本。

另一种方法是使用NSXMLDocument's-objectByApplyingXSLTString方法来应用执行此操作的XSLT转换。

不幸的是,iPhone 不支持NSAttributedStringNSXMLDocument. 有太多的边缘案例和格式错误HTML的文档让我觉得使用 regex 或NSScanner. 有人对此有解决方案吗?

一个建议是简单地查找开始和结束标记字符,除了非常琐碎的情况外,这种方法将不起作用。

例如,这些情况(来自同一主题的 Perl Cookbook 章节)会破坏这种方法:

<IMG SRC = "foo.gif" ALT = "A > B">

<!-- <A comment> -->

<script>if (a<b && a>c)</script>

<![INCLUDE CDATA [ >>>>>>>>>>>> ]]>
4

22 回答 22

310

一种快速且“脏”(删除 < 和 > 之间的所有内容)的解决方案,适用于 iOS >= 3.2:

-(NSString *) stringByStrippingHTML {
  NSRange r;
  NSString *s = [[self copy] autorelease];
  while ((r = [s rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
    s = [s stringByReplacingCharactersInRange:r withString:@""];
  return s;
}

我已将此声明为 os NSString 类别。

于 2011-02-03T13:56:53.850 回答
29

NSString类别使用NSXMLParser来准确HTML删除NSString. 这是一个可以轻松包含到您的项目中.m的单个文件。.h

https://gist.github.com/leighmcculloch/1202238

html然后通过执行以下操作进行剥离:

导入标头:

#import "NSString_stripHtml.h"

然后调用stripHtml:

NSString* mystring = @"<b>Hello</b> World!!";
NSString* stripped = [mystring stripHtml];
// stripped will be = Hello World!!

HTML这也适用于技术上不是的畸形XML

于 2011-09-08T00:41:27.257 回答
11
UITextView *textview= [[UITextView alloc]initWithFrame:CGRectMake(10, 130, 250, 170)];
NSString *str = @"This is <font color='red'>simple</font>";
[textview setValue:str forKey:@"contentToHTMLString"];
textview.textAlignment = NSTextAlignmentLeft;
textview.editable = NO;
textview.font = [UIFont fontWithName:@"vardana" size:20.0];
[UIView addSubview:textview];

对我来说很好

于 2013-06-13T07:08:20.973 回答
9

你可以像下面这样使用

-(void)myMethod
 {

 NSString* htmlStr = @"<some>html</string>";
 NSString* strWithoutFormatting = [self stringByStrippingHTML:htmlStr];

 }

 -(NSString *)stringByStrippingHTML:(NSString*)str
 {
   NSRange r;
   while ((r = [str rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location     != NSNotFound)
  {
     str = [str stringByReplacingCharactersInRange:r withString:@""];
 }
  return str;
 }
于 2013-10-10T09:00:41.733 回答
8

用这个

NSString *myregex = @"<[^>]*>"; //regex to remove any html tag

NSString *htmlString = @"<html>bla bla</html>";
NSString *stringWithoutHTML = [hstmString stringByReplacingOccurrencesOfRegex:myregex withString:@""];

不要忘记将其包含在您的代码中:#import "RegexKitLite.h" 这是下载此 API 的链接:http ://regexkit.sourceforge.net/#Downloads

于 2010-11-12T11:15:27.610 回答
7

看看 NSXMLParser。这是一个 SAX 风格的解析器。您应该能够使用它来检测 XML 文档中的标签或其他不需要的元素并忽略它们,只捕获纯文本。

于 2008-11-10T19:40:12.493 回答
6

这是一个比公认答案更有效的解决方案:

- (NSString*)hp_stringByRemovingTags
{
    static NSRegularExpression *regex = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        regex = [NSRegularExpression regularExpressionWithPattern:@"<[^>]+>" options:kNilOptions error:nil];
    });

    // Use reverse enumerator to delete characters without affecting indexes
    NSArray *matches =[regex matchesInString:self options:kNilOptions range:NSMakeRange(0, self.length)];
    NSEnumerator *enumerator = matches.reverseObjectEnumerator;

    NSTextCheckingResult *match = nil;
    NSMutableString *modifiedString = self.mutableCopy;
    while ((match = [enumerator nextObject]))
    {
        [modifiedString deleteCharactersInRange:match.range];
    }
    return modifiedString;
}

上面的NSString类别使用正则表达式来查找所有匹配的标签,复制原始字符串,最后通过以相反的顺序迭代它们来删除所有的标签。它更有效,因为:

  • 正则表达式只初始化一次。
  • 使用原始字符串的单个副本。

这对我来说表现得足够好,但使用的解决方案NSScanner可能更有效。

与接受的答案一样,此解决方案并未解决@lfalin 要求的所有边境案例。这些将需要更昂贵的解析,而平均用例很可能不需要。

于 2014-03-13T14:45:46.760 回答
5

没有循环(至少在我们这边):

- (NSString *)removeHTML {

    static NSRegularExpression *regexp;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        regexp = [NSRegularExpression regularExpressionWithPattern:@"<[^>]+>" options:kNilOptions error:nil];
    });

    return [regexp stringByReplacingMatchesInString:self
                                            options:kNilOptions
                                              range:NSMakeRange(0, self.length)
                                       withTemplate:@""];
}
于 2014-05-26T00:08:30.363 回答
5
NSAttributedString *str=[[NSAttributedString alloc] initWithData:[trimmedString dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]} documentAttributes:nil error:nil];
于 2015-03-23T09:41:43.163 回答
4
#import "RegexKitLite.h"

string text = [html stringByReplacingOccurrencesOfRegex:@"<[^>]+>" withString:@""]
于 2011-08-12T00:43:37.250 回答
3

如果您想从网页(HTML 文档)中获取不带 html 标记的内容,请在UIWebViewDidfinishLoading 委托方法中使用此代码。

  NSString *myText = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.textContent"];
于 2009-10-05T10:13:15.767 回答
3

我已经扩展了 m.kocikowski 的答案,并试图通过使用 NSMutableString 来提高它的效率。我还构建了它以在静态 Utils 类中使用(我知道 Category 可能是最好的设计),并删除了 autorelease 以便它在 ARC 项目中编译。

包括在这里,以防有人发现它有用。

。H

+ (NSString *)stringByStrippingHTML:(NSString *)inputString;

.m

+ (NSString *)stringByStrippingHTML:(NSString *)inputString 
{
  NSMutableString *outString;

  if (inputString)
  {
    outString = [[NSMutableString alloc] initWithString:inputString];

    if ([inputString length] > 0)
    {
      NSRange r;

      while ((r = [outString rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
      {
        [outString deleteCharactersInRange:r];
      }      
    }
  }

  return outString; 
}
于 2012-08-24T19:51:07.520 回答
2

我想最安全的方法就是解析 <>s,不是吗?循环遍历整个字符串,并将未包含在 <>s 中的任何内容复制到新字符串。

于 2008-11-10T04:56:26.223 回答
2

这是m.kocikowski答案的现代化,它删除了空格:

@implementation NSString (StripXMLTags)

- (NSString *)stripXMLTags
{
    NSRange r;
    NSString *s = [self copy];
    while ((r = [s rangeOfString:@"<[^>]+>\\s*" options:NSRegularExpressionSearch]).location != NSNotFound)
        s = [s stringByReplacingCharactersInRange:r withString:@""];
    return s;
}

@end
于 2013-09-23T21:56:13.530 回答
2

以下是公认的答案,但不是类别,而是简单的辅助方法,其中传递了字符串。(谢谢你 m.kocikowski)

-(NSString *) stringByStrippingHTML:(NSString*)originalString {
    NSRange r;
    NSString *s = [originalString copy];
    while ((r = [s rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
        s = [s stringByReplacingCharactersInRange:r withString:@""];
    return s;
}
于 2015-02-18T23:55:33.653 回答
2

这是快速版本:

func stripHTMLFromString(string: String) -> String {
  var copy = string
  while let range = copy.rangeOfString("<[^>]+>", options: .RegularExpressionSearch) {
    copy = copy.stringByReplacingCharactersInRange(range, withString: "")
  }
  copy = copy.stringByReplacingOccurrencesOfString("&nbsp;", withString: " ")
  copy = copy.stringByReplacingOccurrencesOfString("&amp;", withString: "&")
  return copy
}
于 2015-11-08T12:44:49.543 回答
0

如果你愿意使用Three20 框架,它在 NSString 上有一个类别,添加了 stringByRemovingHTMLTags 方法。请参阅 Three20Core 子项目中的 NSStringAdditions.h。

于 2010-10-04T12:17:59.307 回答
0

更多地从 m.kocikowski 和 Dan J 的答案中扩展这一点,并为新手提供更多解释

1# 首先,您必须创建objective-c-categories以使代码在任何类中都可用。

。H

@interface NSString (NAME_OF_CATEGORY)

- (NSString *)stringByStrippingHTML;

@end

.m

@implementation NSString (NAME_OF_CATEGORY)

- (NSString *)stringByStrippingHTML
{
NSMutableString *outString;
NSString *inputString = self;

if (inputString)
{
    outString = [[NSMutableString alloc] initWithString:inputString];

    if ([inputString length] > 0)
    {
        NSRange r;

        while ((r = [outString rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
        {
            [outString deleteCharactersInRange:r];
        }
    }
}

return outString;
}

@end

2#然后只需导入您刚刚创建的类别类的.h文件,例如

#import "NSString+NAME_OF_CATEGORY.h"

3#调用方法。

NSString* sub = [result stringByStrippingHTML];
NSLog(@"%@", sub);

结果是 NSString 我想从中剥离标签。

于 2013-07-25T20:43:01.403 回答
0

我遵循 m.kocikowski 接受的答案,并稍作修改以使用自动释放池来清理由 stringByReplacingCharactersInRange 创建的所有临时字符串

在此方法的注释中,它声明 /* 用指定字符串替换范围内的字符,返回新字符串。*/

因此,根据 XML 的长度,您可能会创建大量新的自动释放字符串,这些字符串直到下一个 @autoreleasepool 结束时才会被清理。如果您不确定何时会发生这种情况,或者用户操作可能会在此之前反复触发对该方法的多次调用,那么您可以将其包装在 @autoreleasepool 中。这些甚至可以在可能的情况下嵌套并在循环中使用。

Apple 对@autoreleasepool 的引用说明了这一点......“如果您编写一个创建许多临时对象的循环。您可以在循环内使用自动释放池块在下一次迭代之前处理这些对象。在循环中使用自动释放池块有助于减少应用程序的最大内存占用。” 我没有在循环中使用它,但至少这种方法现在可以自行清理。

- (NSString *) stringByStrippingHTML {
    NSString *retVal;
    @autoreleasepool {
        NSRange r;
        NSString *s = [[self copy] autorelease];
        while ((r = [s rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound) {
            s = [s stringByReplacingCharactersInRange:r withString:@""];
        }
        retVal = [s copy];
    } 
    // pool is drained, release s and all temp 
    // strings created by stringByReplacingCharactersInRange
    return retVal;
}
于 2015-04-22T18:56:46.597 回答
0

另一种方式:

界面:

-(NSString *) stringByStrippingHTML:(NSString*)inputString;

执行

(NSString *) stringByStrippingHTML:(NSString*)inputString
{ 
NSAttributedString *attrString = [[NSAttributedString alloc] initWithData:[inputString dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)} documentAttributes:nil error:nil];
NSString *str= [attrString string]; 

//you can add here replacements as your needs:
    [str stringByReplacingOccurrencesOfString:@"[" withString:@""];
    [str stringByReplacingOccurrencesOfString:@"]" withString:@""];
    [str stringByReplacingOccurrencesOfString:@"\n" withString:@""];

    return str;
}

实现

cell.exampleClass.text = [self stringByStrippingHTML:[exampleJSONParsingArray valueForKey: @"key"]];

或简单

NSString *myClearStr = [self stringByStrippingHTML:rudeStr];

于 2016-01-27T10:35:31.783 回答
0

@m.kocikowski 的更新答案适用于最新的 iOS 版本。

-(NSString *) stringByStrippingHTMLFromString:(NSString *)str {
NSRange range;
while ((range = [str rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
    str = [str stringByReplacingCharactersInRange:range withString:@""];
return str;

}

于 2017-10-05T09:54:05.023 回答
-3

这是一篇博客文章,讨论了一些可用于剥离 HTML 的库 http://sugarmaplesoftware.com/25/strip-html-tags/ 请注意提供其他解决方案的注释。

于 2008-11-13T18:02:48.233 回答