Suppression des balises HTML d'une chaîne

95

Comment supprimer les balises HTML d'une chaîne afin de pouvoir générer du texte propre?

let str = string.stringByReplacingOccurrencesOfString("<[^>]+>", withString: "", options: .RegularExpressionSearch, range: nil)
print(str)
LED
la source
Utilisez simplement un analyseur HTML.
Le Croissant Paramagnétique
1
Led, cette question a beaucoup de valeur mais telle quelle, elle risque de se fermer car vous ne posez pas de question claire: c'est un scénario non reproductible. Je vous suggère de reformuler votre question selon Comment demander . Je ne voudrais pas que cette question soit supprimée.
Tunaki
3
lol stackoverflow ... comment est-ce fermé comme "hors sujet"? C'est le résultat Google n ° 1 pour "Swift remove html tags".
canhazbits
2
@canhazbits je sais bien! Cliquez sur rouvrir pour le désigner pour le rouvrir à nouveau.
Led
1
Swift 3: string.replacingOccurrences (of: "<[^>] +>", with: "", options: .regularExpression, range: nil)
etayluz

Réponses:

147

Hmm, j'ai essayé votre fonction et cela a fonctionné sur un petit exemple:

var string = "<!DOCTYPE html> <html> <body> <h1>My First Heading</h1> <p>My first paragraph.</p> </body> </html>"
let str = string.stringByReplacingOccurrencesOfString("<[^>]+>", withString: "", options: .RegularExpressionSearch, range: nil)
print(str)

//output "  My First Heading My first paragraph. "

Pouvez-vous donner un exemple de problème?

Version Swift 4 et 5:

var string = "<!DOCTYPE html> <html> <body> <h1>My First Heading</h1> <p>My first paragraph.</p> </body> </html>"
let str = string.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil)
Steve Rosenberg
la source
25
<LOL> Ha Ha! </LOL>
Steve Rosenberg
1
Par exemple, essayez ce morceau de HTML:<p foo=">now what?">Paragraph</p>
The Paramagnetic Croissant
32
In Swift 3 string.replacingOccurrences(of: "<[^>]+>", with: "", options: String.CompareOptions.regularExpression, range: nil)
Husam
5
Dans Swift 4 string.replacingOccurrences (of: "<[^>] +>", with: "", options: .regularExpression, range: nil)
Raegtime
29

Étant donné que HTML n'est pas un langage standard (HTML est un langage sans contexte ), vous ne pouvez pas utiliser d'expressions régulières. Voir: Utilisation d'expressions régulières pour analyser le HTML: pourquoi pas?

J'envisagerais d'utiliser NSAttributedString à la place.

let htmlString = "LCD Soundsystem was the musical project of producer <a href='http://www.last.fm/music/James+Murphy' class='bbcode_artist'>James Murphy</a>, co-founder of <a href='http://www.last.fm/tag/dance-punk' class='bbcode_tag' rel='tag'>dance-punk</a> label <a href='http://www.last.fm/label/DFA' class='bbcode_label'>DFA</a> Records. Formed in 2001 in New York City, New York, United States, the music of LCD Soundsystem can also be described as a mix of <a href='http://www.last.fm/tag/alternative%20dance' class='bbcode_tag' rel='tag'>alternative dance</a> and <a href='http://www.last.fm/tag/post%20punk' class='bbcode_tag' rel='tag'>post punk</a>, along with elements of <a href='http://www.last.fm/tag/disco' class='bbcode_tag' rel='tag'>disco</a> and other styles. <br />"    
let htmlStringData = htmlString.dataUsingEncoding(NSUTF8StringEncoding)!
let options: [String: AnyObject] = [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: NSUTF8StringEncoding]
let attributedHTMLString = try! NSAttributedString(data: htmlStringData, options: options, documentAttributes: nil)
let string = attributedHTMLString.string

Ou, comme le ferait Irshad Mohamed dans les commentaires:

let attributed = try NSAttributedString(data: htmlString.data(using: .unicode)!, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
print(attributed.string)
Joony
la source
7
Cela semble être l'approche la plus propre et cela fonctionne à merveille! Il est préférable de laisser le framework Foundation testé pour vous, au lieu d'écrire des analyseurs floconneux vous-même.
Shyam Bhat
4
Nettoyer!! let attributed = try NSAttributedString(data: htmlString.data(using: .unicode)!, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) print(attributed.string)la plupart des gens préfèrent choisir des réponses petites et faciles à comprendre.
Irshad Mohamed
1
Merci pour la solution! Est-il possible de sauvegarder les espaces et les sauts de ligne pendant que nous supprimons les balises html? Actuellement, tous les sauts de ligne ne sont pas pris en compte dans la nouvelle chaîne.
Astha Gupta
7
Juste un avertissement en utilisant ceci: la conversion (attribution) du style HTML est lente! . Un ingénieur CoreText de la WWDC m'a dit que ce n'était plus maintenu et qu'il l'avait complètement oublié.
Sirens
1
Juste un avertissement concernant l'avertissement précédent: voyons quelques données avant de rejeter une méthode pour être trop "lente". Il existe de nombreuses bibliothèques C que vous utilisez (souvent sans vous en rendre compte) qui ne nécessitent pas beaucoup de maintenance. Ce n'est pas nécessairement une mauvaise chose.
Joony
10

Solution Mohamed mais en tant qu'extension String dans Swift 4.

extension String {

    func stripOutHtml() -> String? {
        do {
            guard let data = self.data(using: .unicode) else {
                return nil
            }
            let attributed = try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
            return attributed.string
        } catch {
            return nil
        }
    }
}
Andrew
la source
8

J'utilise l'extension suivante pour supprimer des éléments HTML spécifiques:

extension String {
    func deleteHTMLTag(tag:String) -> String {
        return self.stringByReplacingOccurrencesOfString("(?i)</?\(tag)\\b[^<]*>", withString: "", options: .RegularExpressionSearch, range: nil)
    }

    func deleteHTMLTags(tags:[String]) -> String {
        var mutableString = self
        for tag in tags {
            mutableString = mutableString.deleteHTMLTag(tag)
        }
        return mutableString
    }
}

Cela permet de supprimer uniquement les <a>balises d'une chaîne, par exemple:

let string = "my html <a href="">link text</a>"
let withoutHTMLString = string.deleteHTMLTag("a") // Will be "my  html link text"
Antoine
la source
@Mr Lister existe-t-il un moyen de supprimer toutes les balises html et de conserver ce <a href=""> texte du lien </a>?
Mazen Kasser
6
extension String{
    var htmlStripped : String{
        return self.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil)
    }
}

Codage heureux

Benny Davidovitz
la source
3

rapide 4:

extension String {
    func deleteHTMLTag(tag:String) -> String {
        return self.replacingOccurrences(of: "(?i)</?\(tag)\\b[^<]*>", with: "", options: .regularExpression, range: nil)
    }

    func deleteHTMLTags(tags:[String]) -> String {
        var mutableString = self
        for tag in tags {
            mutableString = mutableString.deleteHTMLTag(tag: tag)
        }
        return mutableString
    }
}
Logique
la source
2
ou vous pouvez utiliser comme ceci: func deleteHTMLTag () -> String {return self.replacingOccurrences (of: "(? i) </? \\ b [^ <] *>", avec: "", options: .regularExpression , intervalle: nil)}
Anil Kumar
Cette regex ne supprime pas le code html pour moi. Exemple de chaîne: "<b> Les chats aiment </b> faire quelque chose". N'a pas enquêté davantage sur la raison pour laquelle cela ne fonctionne pas Mais text.replacingOccurrences (of: "<[^>] +>", ....) fonctionne pour mes cas simples.
Benjamin Piette
2

Mis à jour pour Swift 4:

guard let htmlStringData = htmlString.data(using: .unicode) else { fatalError() }

let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
                .documentType: NSAttributedString.DocumentType.html
                .characterEncoding: String.Encoding.unicode.rawValue
             ]

let attributedHTMLString = try! NSAttributedString(data: htmlStringData, options: options, documentAttributes: nil)
let string = attributedHTMLString.string
Lee Irvine
la source
il vous manque un ',' après le .documentType: param
cwgso
0

Je préfère utiliser une expression régulière que d'utiliser la conversion HTML NSAttributedString, sachez que cela prend beaucoup de temps et doit également être exécuté sur le thread principal. Plus d'informations ici: https://developer.apple.com/documentation/foundation/nsattributedstring/1524613-initwithdata

Pour moi, cela a fait l'affaire, d'abord je supprime tout style en ligne CSS, puis toutes les balises HTML. Probablement pas solide comme l'option NSAttributedString, mais beaucoup plus rapide pour mon cas.

extension String {
    func withoutHtmlTags() -> String {
        let str = self.replacingOccurrences(of: "<style>[^>]+</style>", with: "", options: .regularExpression, range: nil)
        return str.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil)
    }
}
pegpeg
la source