Removendo tags HTML de uma string

95

Como faço para remover tags HTML de uma string para que eu possa produzir um texto limpo?

let str = string.stringByReplacingOccurrencesOfString("<[^>]+>", withString: "", options: .RegularExpressionSearch, range: nil)
print(str)
Conduziu
fonte
Basta usar um analisador HTML.
O Croissant Paramagnético de
1
Conduzida, essa pergunta tem muito valor, mas como está, é provável que seja fechada porque você não faz uma pergunta clara: é um cenário não reproduzível. Eu sugiro que você reformule sua pergunta de acordo com How to Ask . Eu não gostaria que essa pergunta fosse excluída.
Tunaki,
3
lol stackoverflow ... como isso é fechado como "fora do tópico"? É o resultado nº 1 do Google para "Remoção de tags html Swift".
canhazbits de
2
@canhazbits eu sei né! Clique em reabrir para indicá-lo para reabrir novamente.
Liderado em
1
Swift 3: string.replacingOccurrences (of: "<[^>] +>", com: "", opções: .regularExpression, range: nil)
etayluz

Respostas:

147

Hmm, eu tentei sua função e funcionou em um pequeno exemplo:

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

Você pode dar um exemplo de um problema?

Versão Swift 4 e 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
fonte
25
<LOL> Ha Ha! </LOL>
Steve Rosenberg
1
Por exemplo, experimente este pedaço de HTML:<p foo=">now what?">Paragraph</p>
O Croissant Paramagnético de
32
In Swift 3 string.replacingOccurrences(of: "<[^>]+>", with: "", options: String.CompareOptions.regularExpression, range: nil)
Husam
5
Em Swift 4 string.replacingOccurrences (of: "<[^>] +>", com: "", options: .regularExpression, range: nil)
Raegtime
29

Visto que HTML não é uma linguagem regular (HTML é uma linguagem livre de contexto ), você não pode usar Expressões regulares. Consulte: Usando expressões regulares para analisar HTML: por que não?

Eu consideraria usar NSAttributedString em vez disso.

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, como faria Irshad Mohamed nos comentários:

let attributed = try NSAttributedString(data: htmlString.data(using: .unicode)!, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
print(attributed.string)
Joony
fonte
7
Esta parece ser a abordagem mais limpa e funciona maravilhosamente bem! É melhor deixar a estrutura do Foundation testada em batalhas cuidar disso para você, em vez de escrever analisadores fragmentados por conta própria.
Shyam Bhat
4
Limpar \ limpo!! let attributed = try NSAttributedString(data: htmlString.data(using: .unicode)!, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) print(attributed.string)a maioria das pessoas prefere escolher respostas pequenas e fáceis de entender.
Irshad Mohamed
1
Obrigado pela solução! É possível salvar os espaços e quebras de linha enquanto removemos as tags html? Atualmente, todas as quebras de linha são desconsideradas na nova string.
Astha Gupta
7
Apenas um aviso usando isto: conversão (atribuição) de estilo HTML lenta! . Um engenheiro da CoreText da WWDC me disse que isso não é mais mantido e que ele se esqueceu completamente disso.
Sirenes de
1
Só um aviso sobre o aviso anterior: vamos ver alguns dados antes de descartar um método por ser muito "lento". Existem muitas bibliotecas C que você usa (muitas vezes sem perceber) que não requerem muita manutenção. Isso não é necessariamente uma coisa ruim.
Joony,
10

Solução de Mohamed, mas como uma extensão de String em 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
fonte
8

Estou usando a seguinte extensão para remover 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
    }
}

Isso torna possível remover apenas <a>tags de uma string, por exemplo:

let string = "my html <a href="">link text</a>"
let withoutHTMLString = string.deleteHTMLTag("a") // Will be "my  html link text"
Antoine
fonte
@Mr Lister existe uma maneira de remover todas as tags html e manter este <a href=""> texto do link </a>?
Mazen Kasser
6
extension String{
    var htmlStripped : String{
        return self.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil)
    }
}

Happy Coding

Benny Davidovitz
fonte
3

4 rápido:

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
fonte
2
ou você pode usar assim: func deleteHTMLTag () -> String {return self.replacingOccurrences (of: "(? i) </? \\ b [^ <] *>", com: "", opções: .regularExpression , range: nil)}
Anil Kumar
Este regex não remove o código html para mim. String de exemplo: "<b> Gatos gostam </b> de fazer algo". Não investiguei mais por que não funciona. Mas text.replacingOccurrences (of: "<[^>] +>", ....) funciona para meus casos simples.
Benjamin Piette
2

Atualizado 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
fonte
está faltando um ',' após o .documentType: param
cwgso
0

Eu prefiro usar uma expressão regular do que usar a conversão HTML NSAttributedString, esteja ciente de que consome muito tempo e precisa ser executado no thread principal também. Mais informações aqui: https://developer.apple.com/documentation/foundation/nsattributedstring/1524613-initwithdata

Para mim, isso funcionou, primeiro removo qualquer estilo CSS embutido e, depois, todas as tags HTML. Provavelmente não é sólido como a opção NSAttributedString, mas é muito mais rápido para o meu 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
fonte