Le problème avec RegEx
Ceci est une méthode de remplacement RegEx très simple qui supprime les balises HTML d'un HTML bien formaté dans une chaîne.
strip_html_regex.go
package main
import "regexp"
const regex = `<.*?>`
// Cette méthode utilise une expression régulière pour supprimer les balises HTML.
func stripHtmlRegex(s string) string {
r := regexp.MustCompile(regex)
return r.ReplaceAllString(s, "")
}
Note : cela ne fonctionne pas bien avec du HTML malformé. Ne pas utiliser ceci.
Une meilleure façon
Étant donné qu'une chaîne en Go peut être traitée comme une tranche d'octets, il est facile de parcourir la chaîne et de trouver les parties qui ne sont pas dans une balise HTML. Lorsque nous identifions une partie valide de la chaîne, nous pouvons simplement prendre une tranche de cette partie et l'ajouter en utilisant un strings.Builder
.
strip_html.go
package main
import (
"strings"
"unicode/utf8"
)
const (
htmlTagStart = 60 // Unicode `<`
htmlTagEnd = 62 // Unicode `>`
)
// Supprime agressivement les balises HTML d'une chaîne.
// Il ne laissera que ce qui se trouve entre `>` et `<`.
func stripHtmlTags(s string) string {
// Configuration d'un constructeur de chaîne et allocation de suffisamment de mémoire pour la nouvelle chaîne.
var builder strings.Builder
builder.Grow(len(s) + utf8.UTFMax)
in := false // Vrai si nous sommes à l'intérieur d'une balise HTML.
start := 0 // L'index du caractère de début de balise précédent `<`
end := 0 // L'index du caractère de fin de balise précédent `>`
for i, c := range s {
// Si c'est le dernier caractère et que nous ne sommes pas dans une balise HTML, sauvegardez-le.
if (i+1) == len(s) && end >= start {
builder.WriteString(s[end:])
}
// Continuez si le caractère n'est pas `<` ou `>`
if c != htmlTagStart && c != htmlTagEnd {
continue
}
if c == htmlTagStart {
// Mettre à jour le début seulement si nous ne sommes pas dans une balise.
// Cela garantit que nous supprimons `<` et non seulement ``
if !in {
start = i
}
in = true
// Écrire la chaîne valide entre la fermeture et le début des deux balises.
builder.WriteString(s[end:start])
continue
}
// else c == htmlTagEnd
in = false
end = i + 1
}
s = builder.String()
return s
}
Si nous exécutons ces deux fonctions avec le texte de l'OP et du HTML malformé, vous verrez que le résultat n'est pas cohérent.
main.go
package main
import "fmt"
func main() {
s := "afsdf4534534!@@!!#345345afsdf4534534!@@!!#"
res := stripHtmlTags(s)
fmt.Println(res)
// Exemples de HTML malformé
fmt.Println("\n:: stripHTMLTags ::\n")
fmt.Println(stripHtmlTags("Faites quelque chose de gras."))
fmt.Println(stripHtmlTags("h1>J'ai cassé cela"))
fmt.Println(stripHtmlTags("Ceci est un >lien cassé."))
fmt.Println(stripHtmlTags("Je ne sais pas >gras."))
fmt.Println(stripHtmlTags("h1>J'ai cassé cela"))
fmt.Println(stripHtmlTags("Ceci est un >lien cassé."))
fmt.Println(stripHtmlTags("Je ne sais pas >
``Résultat :
afsdf4534534!@@!!#345345afsdf4534534!@@!!#
:: stripHTMLTags ::
Faites quelque chose de gras.
J'ai cassé cela
Ceci est un lien cassé.
où commencer cette balise
:: stripHtmlRegex ::
Faites quelque chose de gras.
J'ai cassé cela
Ceci est un >lien cassé.
Je ne sais pas >où commencer cette balise<.
Notez que la méthode RegEx ne supprime pas toutes les balises HTML de manière cohérente. Pour être honnête, je ne suis pas assez bon en RegEx pour écrire une chaîne de correspondance RegEx pour gérer correctement la suppression de HTML.
Benchmark
Outre l'avantage d'être plus sûr et plus agressif dans la suppression des balises HTML malformées, stripHtmlTags
est environ 4 fois plus rapide que stripHtmlRegex
.
> go test -run=Calculate -bench=.
goos: windows
goarch: amd64
BenchmarkStripHtmlRegex-8 51516 22726 ns/op
BenchmarkStripHtmlTags-8 230678 5135 ns/op``