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)


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)

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)

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

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"

@ 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


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

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

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)
    }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.