HTML-tags verwijderen van een NSString op de iPhone

Er zijn een aantal verschillende manieren om HTML tagste verwijderen van een NSStringin Cocoa.

Eén manieris om de string om te zetten in een NSAttributedStringen pak dan de weergegeven tekst.

Een andere manieris om NSXMLDocument'sobjectByApplyingXSLTStringmethode om een ​​XSLT-transformatie toe te passen die dit doet.

Helaas ondersteunt de iPhone geen NSAttributedStringof NSXMLDocument. Er zijn te veel randgevallen en misvormde HTML-documenten om me op mijn gemak te voelen bij het gebruik van regex of NSScanner. Heeft iemand hier een oplossing voor?

Eén suggestie was om gewoon te zoeken naar tekens voor het openen en sluiten van tags, deze methode zal niet werken, behalve in zeer triviale gevallen.

Bijvoorbeeld deze gevallen (uit het Perl Cookbook-hoofdstuk over hetzelfde onderwerp) zouden deze methode breken:

<IMG SRC = "foo.gif" ALT = "A > B">
<!-- <A comment> -->
<script>if (a<b && a>c)</script>
<![INCLUDE CDATA [ >>>>>>>>>>>> ]]>

Antwoord 1, autoriteit 100%

Een snelle en “vuile” (verwijdert alles tussen < en >) oplossing, werkt met 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;
}

Ik heb dit gedeclareerd als een categorie os NSString.


Antwoord 2, autoriteit 9%

Deze categorie NSStringgebruikt de NSXMLParserom nauwkeurig alle HTML-tags van een NSStringte verwijderen. Dit is een enkel .m– en .h-bestand dat gemakkelijk in uw project kan worden opgenomen.

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

Vervolgens strip je HTMLdoor het volgende te doen:

De koptekst importeren:

#import "NSString_stripHtml.h"

En bel dan stripHtml:

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

Dit werkt ook met misvormde HTMLdie technisch gezien geen XMLis.


Antwoord 3, autoriteit 4%

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

werk prima voor mij


Antwoord 4, autoriteit 3%

U kunt gebruiken zoals hieronder

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

5, Autoriteit 2%

Bekijk NSXMLPARSER. Het is een SAX-stijl Parser. U moet het kunnen gebruiken om tags of andere ongewenste elementen in het XML-document te detecteren en ze te negeren, alleen pure tekst vast te leggen.


6

Ik heb het antwoord door M.kocikowski uitgebreid en probeerde het een beetje efficiënter te maken door een NSMutableString te gebruiken. Ik heb het ook gestructureerd voor gebruik in een Statische UTILS-klasse (ik weet dat een categorie waarschijnlijk het beste ontwerp is) en verwijderde de autorelease, zodat het compileert in een ARC-project.

Hier opgenomen voor het geval iemand het nuttig vindt.

.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; 
}

Antwoord 7

Als je de inhoud zonder de html-tags van de webpagina (HTML-document) wilt halen, gebruik dan deze code binnen de UIWebViewDidfinishLoadingdelegate-methode.

 NSString *myText = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.textContent"];

Antwoord 8

Ik kan me voorstellen dat de veiligste manier zou zijn om gewoon te parseren op <>s, niet? Loop door de hele string en kopieer alles wat niet tussen <>s staat, naar een nieuwe string.


Antwoord 9

Dit is de modernisering van het antwoord van m.kocikowskidat spaties verwijdert:

@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

Antwoord 10

Hier volgt het geaccepteerde antwoord, maar in plaats van categorie is het een eenvoudige hulpmethode met een string erin. (dank je 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;
}

Antwoord 11

Hier is de snelle versie:

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
}

Antwoord 12

Als je bereid bent om Three20 frameworkte gebruiken, heeft het een categorie op NSString die de stringByRemovingHTMLtags-methode toevoegt. Zie NSStringAdditions.h in het Three20Core-subproject.


Antwoord 13

Dit uitbreiden van de antwoorden van m.kocikowski en Dan J met meer uitleg voor nieuwelingen

1# Eerst moet je objective-c-categoriesom de code bruikbaar te maken in elke klas.

.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# Importeer dan gewoon het bestand .hvan de categorieklasse die je zojuist hebt gemaakt, bijvoorbeeld

#import "NSString+NAME_OF_CATEGORY.h"

3# De methode aanroepen.

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

resultaatis NSString waarvan ik de tags wil verwijderen.


Antwoord 14

Ik heb het geaccepteerde antwoord van m.kocikowski gevolgd en is enigszins aangepast om gebruik te maken van een autoreleasepool om alle tijdelijke strings op te schonen die zijn gemaakt door stringByReplacingCharactersInRange

In de opmerking voor deze methode staat: /* Vervang tekens in het bereik door de opgegeven tekenreeks, waarbij een nieuwe tekenreeks wordt geretourneerd.
*/

Dus, afhankelijk van de lengte van uw XML, maakt u mogelijk een enorme stapel nieuwe autorelease-strings die pas aan het einde van de volgende @autoreleasepool zijn opgeschoond. Als u niet zeker weet wanneer dat kan gebeuren of als een gebruikersactie herhaaldelijk veel oproepen naar deze methode kan veroorzaken, kunt u dit gewoon in een @autoreleasepool afronden. Deze kunnen zelfs worden genest en waar mogelijk in lussen worden gebruikt.

Apple’s referentie op @autoreleasepool stelt dit… “Als u een lus schrijft die veel tijdelijke objecten creëert. U kunt een automatisch vrijgeven poolblok in de lus gebruiken om die objecten te verwijderen voor de volgende iteratie. Een autorelease poolblok gebruiken in the loop helpt om de maximale geheugenvoetafdruk van de applicatie te verkleinen.” Ik heb het niet in de loop gebruikt, maar deze methode ruimt zichzelf nu op.

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

Antwoord 15

Een andere manier:

Interface:

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

Implementatie

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

Realisatie

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

of eenvoudig

NSString *myClearStr = [self stringByStrippingHTML:rudeStr];


Antwoord 16

Een bijgewerkt antwoord voor @m.kocikowski dat werkt op recente iOS-versies.

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

}


Antwoord 17

Hier is een blogpost waarin een aantal bibliotheken worden besproken die beschikbaar zijn voor het strippen van HTML
http://sugarmaplesoftware.com/25/strip-html-tags/
Let op de opmerkingen waar andere oplossingen worden aangeboden.

Other episodes