Eliminar etiquetas HTML de una cadena

95

¿Cómo elimino las etiquetas HTML de una cadena para poder generar texto limpio?

let str = string.stringByReplacingOccurrencesOfString("<[^>]+>", withString: "", options: .RegularExpressionSearch, range: nil)
print(str)
LED
fuente
Simplemente use un analizador HTML.
El Croissant Paramagnético
1
Dirigida, esta pregunta tiene mucho valor, pero tal como está, es probable que se cierre porque no hace una pregunta clara: es un escenario no reproducible. Le sugiero que reformule su pregunta según Cómo preguntar . No quisiera que se borrara esa pregunta.
Tunaki
3
lol stackoverflow ... ¿cómo se cierra esto como "fuera de tema"? Es el resultado número uno de Google para "Eliminación rápida de etiquetas html".
canhazbits
2
@canhazbits ¡lo sé bien! Haga clic en reabrir para nominarlo y volver a abrirlo.
Lideró el
1
Swift 3: string.replacingOccurrences (of: "<[^>] +>", con: "", opciones: .regularExpression, rango: nil)
etayluz

Respuestas:

147

Hmm, probé tu función y funcionó en un pequeño ejemplo:

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. "

¿Puede dar un ejemplo de un problema?

Versión Swift 4 y 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
fuente
25
<LOL> ¡Ja, ja! </LOL>
Steve Rosenberg
1
Por ejemplo, pruebe este fragmento de HTML:<p foo=">now what?">Paragraph</p>
El croissant paramagnético
32
En Swift 3 string.replacingOccurrences(of: "<[^>]+>", with: "", options: String.CompareOptions.regularExpression, range: nil)
Husam
5
En Swift 4 string.replacingOccurrences (de: "<[^>] +>", con: "", opciones: .regularExpression, rango: nil)
Raegtime
29

Dado que HTML no es un lenguaje normal (HTML es un lenguaje sin contexto ), no puede utilizar expresiones regulares. Consulte: Uso de expresiones regulares para analizar HTML: ¿por qué no?

En su lugar, consideraría usar NSAttributedString.

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

O, como lo haría Irshad Mohamed en los comentarios:

let attributed = try NSAttributedString(data: htmlString.data(using: .unicode)!, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
print(attributed.string)
Joony
fuente
7
¡Este parece ser el enfoque más limpio y funciona maravillosamente bien! Es mejor dejar que el marco Foundation probado en batalla se encargue de esto por usted, en lugar de escribir analizadores inusuales por su cuenta.
Shyam Bhat
4
¡¡Limpiar!! let attributed = try NSAttributedString(data: htmlString.data(using: .unicode)!, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) print(attributed.string)la mayoría de la gente prefiere elegir respuestas pequeñas y fáciles de entender.
Irshad Mohamed
1
¡Gracias por la solución! ¿Es posible guardar los espacios y los saltos de línea mientras eliminamos las etiquetas html? Actualmente, todos los saltos de línea se ignoran en la nueva cadena.
Astha Gupta
7
Solo una advertencia usando esto: ¡ conversión (atribución) de estilo HTML lento! . Un ingeniero de CoreText en la WWDC me dijo que esto ya no se mantiene y que se había olvidado por completo.
Sirenas
1
Solo una advertencia sobre la advertencia anterior: Veamos algunos datos antes de descartar un método por ser demasiado "lento". Hay muchas bibliotecas de C que usa (a menudo sin darse cuenta) que no requieren mucho mantenimiento. Eso no es necesariamente algo malo.
Joony
10

Solución de Mohamed pero como una extensión de String en 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
        }
    }
}
Andrés
fuente
8

Estoy usando la siguiente extensión para eliminar elementos HTML específicos:

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

Esto hace posible eliminar solo <a>etiquetas de una cadena, por ejemplo:

let string = "my html <a href="">link text</a>"
let withoutHTMLString = string.deleteHTMLTag("a") // Will be "my  html link text"
Antoine
fuente
@ Sr. Lister, ¿hay alguna manera de eliminar todas las etiquetas html y mantener este <a href=""> texto del enlace </a>?
Mazen Kasser
6
extension String{
    var htmlStripped : String{
        return self.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil)
    }
}

Codificación feliz

Benny Davidovitz
fuente
3

rápido 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
    }
}
Lógica
fuente
2
o puede usar así: func deleteHTMLTag () -> String {return self.replacingOccurrences (of: "(? i) </? \\ b [^ <] *>", con: "", opciones: .regularExpression , rango: nulo)}
Anil Kumar
Esta expresión regular no elimina el código html para mí. Cadena de ejemplo: "<b> A los gatos les gusta </b> hacer algo". No investigué más por la razón por la que no funciona. Pero text.replacingOccurrences (of: "<[^>] +>", ....) funciona para mis casos simples.
Benjamin Piette
2

Actualizado para 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
fuente
te falta un ',' después del .documentType: param
cwgso
0

Prefiero usar una expresión regular que usar la conversión HTML NSAttributedString, tenga en cuenta que consume bastante tiempo y también debe ejecutarse en el hilo principal. Más información aquí: https://developer.apple.com/documentation/foundation/nsattributedstring/1524613-initwithdata

Para mí, esto hizo el truco, primero elimino cualquier estilo CSS en línea y luego todas las etiquetas HTML. Probablemente no sea sólido como la opción NSAttributedString, pero mucho más rápido para mi caso.

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
fuente