web-dev-qa-db-fra.com

Conversion de texte HTML en texte brut à l'aide d'Objective-C

J'ai un NSString énorme avec du texte HTML à l'intérieur. La longueur de cette chaîne dépasse 3.500.000 caractères. Comment puis-je convertir ce texte HTML en NSString avec du texte brut à l'intérieur. J'utilisais un scanner, mais cela fonctionne trop lentement. Une idée ?

24

Je résous ma question avec le scanner, mais je ne l'utilise pas pour tout le texte. Je l'utilise pour chaque 10.000 parties de texte, avant de concaténer toutes les parties ensemble. Mon code ci-dessous

-(NSString *)convertHTML:(NSString *)html {

    NSScanner *myScanner;
    NSString *text = nil;
    myScanner = [NSScanner scannerWithString:html];

    while ([myScanner isAtEnd] == NO) {

        [myScanner scanUpToString:@"<" intoString:NULL] ;

        [myScanner scanUpToString:@">" intoString:&text] ;

        html = [html stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@>", text] withString:@""];
    }
    //
    html = [html stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

    return html;
}

Swift 4:

var htmlToString(html:String) -> String {
        var htmlStr =html;
        let scanner:Scanner = Scanner(string: htmlStr);
        var text:NSString? = nil;
        while scanner.isAtEnd == false {
            scanner.scanUpTo("<", into: nil);
            scanner.scanUpTo(">", into: &text);
            htmlStr = htmlStr.replacingOccurrences(of: "\(text ?? "")>", with: "");
        }
        htmlStr = htmlStr.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines);
        return htmlStr;
}
16

Cela dépend de la version iOS que vous ciblez. Depuis iOS7, il existe une méthode intégrée qui non seulement supprime les balises HTML, mais met également la mise en forme dans la chaîne:

Xcode 9/Swift 4

if let htmlStringData = htmlString.data(using: .utf8), let attributedString = try? NSAttributedString(data: htmlStringData, options: [.documentType : NSAttributedString.DocumentType.html], documentAttributes: nil) {
    print(attributedString)
}

Vous pouvez même créer une extension comme celle-ci:

extension String {
    var htmlToAttributedString: NSAttributedString? {
        guard let data = self.data(using: .utf8) else {
            return nil
        }

        do {
            return try NSAttributedString(data: data, options: [.documentType : NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
        } catch {
            print("Cannot convert html string to attributed string: \(error)")
            return nil
        }
    }
}

Notez que cet exemple de code utilise le codage UTF8. Vous pouvez même créer une fonction au lieu d'une propriété calculée et ajouter le codage en tant que paramètre.

Swift 3

let attributedString = try NSAttributedString(data: htmlString.dataUsingEncoding(NSUTF8StringEncoding)!,
                                              options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
                                              documentAttributes: nil)

Objectif c

[[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]} documentAttributes:nil error:nil];

Si vous avez juste besoin de tout supprimer entre < et > (façon sale !!!), ce qui pourrait poser problème si vous avez ces caractères dans la chaîne, utilisez ceci:

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

Pour la langue rapide,

NSAttributedString(data:(htmlString as! String).dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true
            )!, options:[NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: NSNumber(unsignedLong: NSUTF8StringEncoding)], documentAttributes: nil, error: nil)!
1
Rabindra Nath Nandi

Objectif c

+ (NSString*)textToHtml:(NSString*)htmlString
{
    htmlString = [htmlString stringByReplacingOccurrencesOfString:@"&quot;" withString:@"\""];
    htmlString = [htmlString stringByReplacingOccurrencesOfString:@"&apos;" withString:@"'"];
    htmlString = [htmlString stringByReplacingOccurrencesOfString:@"&amp;" withString:@"&"];
    htmlString = [htmlString stringByReplacingOccurrencesOfString:@"&lt;" withString:@"<"];
    htmlString = [htmlString stringByReplacingOccurrencesOfString:@"&gt;" withString:@">"];
    return htmlString;
}

J'espère que cela t'aides!

1
- (NSString *)stringByStrippingHTML:(NSString *)inputString
{
    NSMutableString *outString;

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

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

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

    return outString; 
}
1
Ahmed Abdallah

Il peut être plus générique en passant le type de codage en paramètre, mais à titre d'exemple: 

- (NSString *)htmlToText {
    return [NSAttributedString.alloc
            initWithData:[self dataUsingEncoding:NSUnicodeStringEncoding]
                 options:@{NSDocumentTypeDocumentOption: NSHTMLTextDocumentType}
      documentAttributes:nil error:nil].string;
}
0
Renetik

Swift 4:

do {
   let cleanString = try NSAttributedString(data: htmlContent.data(using: String.Encoding.utf8)!,
                                                                      options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
                                                                      documentAttributes: nil)
} catch {
    print("Something went wrong")
}
0
Josh O'Connor

Avez-vous essayé quelque chose dans ce sens ci-dessous? Vous n’êtes pas sûr que cela ira plus vite que vous l’avez fait avant d’utiliser le scanner, vérifiez: -

//String which contains html tags
    NSString *htmlString=[NSString stringWithFormat:@"%@",@"<b>right</b> onto <b>Kennington Park Rd/A3</b>Continue to follow A3</div><div >Entering toll zone in 1.7&nbsp;km at Newington Causeway/A3</div><divGo through 2 roundabouts</div>"];


    NSMutableString *mutStr=[NSMutableString string];
    NSString *s = nil;
//Removing html elements tags
    NSArray *arra=[htmlString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"</>"]];
    NSLog(@"%@",arra);
    for (s in arra)
    {
        [mutStr appendString:@" "];
        [mutStr appendString:s];
    }
            NSLog(@"%@",mutStr);//Printing the output
0
Hussain Shabbir