Удалить HTML-теги из NSString на iPhone - PullRequest
104 голосов
/ 10 ноября 2008

Существует несколько способов удаления HTML tags из NSString в Cocoa.

Один из способов - преобразовать строку в NSAttributedString, а затем получить обработанный текст.

Другой способ - использовать метод NSXMLDocument's - objectByApplyingXSLTString для применения преобразования XSLT, которое это делает.

К сожалению, iPhone не поддерживает NSAttributedString или NSXMLDocument. Слишком много крайних случаев и искаженных документов HTML, чтобы я чувствовал себя комфортно, используя регулярные выражения или NSScanner. У кого-нибудь есть решение этого?

Одним из предложений было просто искать открывающие и закрывающие символы тега, этот метод не будет работать, за исключением очень тривиальных случаев.

Например, в этих случаях (из главы Perl Cookbook на ту же тему) этот метод будет нарушен:

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

<!-- <A comment> -->

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

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

Ответы [ 22 ]

3 голосов
/ 24 августа 2012

Я расширил ответ m.kocikowski и попытался сделать его немного более эффективным, используя NSMutableString. Я также структурировал его для использования в статическом классе Utils (я знаю, что Категория, вероятно, является лучшим дизайном, хотя) и удалил авто-релиз, чтобы он компилировался в проекте 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; 
}
3 голосов
/ 05 октября 2009

Если вы хотите получить содержимое без тегов html с веб-страницы (HTML-документ), используйте этот код в методе UIWebViewDidfinishLoading делегат .

  NSString *myText = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.textContent"];
2 голосов
/ 24 сентября 2013

Это модернизация ответа 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
2 голосов
/ 10 ноября 2008

Я бы предположил, что самый безопасный способ - это просто проанализировать <> s, нет? Переберите всю строку и скопируйте все, что не заключено в <>, в новую строку.

2 голосов
/ 19 февраля 2015

следующий является принятым ответом, но вместо категории это простой вспомогательный метод с переданной строкой. (спасибо 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;
}
1 голос
/ 08 ноября 2015

Вот быстрая версия:

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
}
0 голосов
/ 22 апреля 2015

Я следую принятому ответу 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;
}
0 голосов
/ 13 ноября 2008

Вот сообщение в блоге, в котором обсуждаются несколько библиотек, доступных для разметки HTML. http://sugarmaplesoftware.com/25/strip-html-tags/ Обратите внимание на комментарии, где предлагаются другие решения.

0 голосов
/ 04 октября 2010

Если вы хотите использовать Three20 framework , у него есть категория на NSString, которая добавляет метод stringByRemovingHTMLTags. См. NSStringAdditions.h в подпроекте Three20Core.

0 голосов
/ 27 января 2016

Еще один способ:

Интерфейс:

-(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];

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...