Regex balise HTML
La réponse la plus célèbre de Stack Overflow (4400 votes, verrouillée) le dit sans détour : le HTML imbriqué ne se parse pas avec une regex, ce n'est pas un langage régulier. Mais reconnaître UNE balise isolée — pas un document entier — reste un usage légitime. Voici un motif pour ça, comparé à la regex « attrape-tout » à 235 votes et à la tentative de l'auteur de la question elle-même, que notre analyse ReDoS classe vulnérable.
/^<([a-zA-Z][a-zA-Z0-9]*)((?:\s+[a-zA-Z-]+(?:\s*=\s*(?:"[^"]*"|'[^']*'))?)*)\s*(\/)?>$/passe 20/20 cas
Comparatif des patterns existants
| Source | pattern | Score sur le corpus | ReDoS |
|---|---|---|---|
| Stack Overflow — regex « attrape-tout » la plus copiée pour nettoyer du HTML, 235 votes | ^<[^>]*>$ | 13 / 20 | sûr |
| Stack Overflow — tentative de l'auteur de la question de référence (« ai-je bien compris ? ») | ^<([a-z]+) *[^/]*?>$ | 14 / 20 | vulnérable (<a …) |
| Stack Overflow — réponse structurée avec attributs entre guillemets, 103 votes | ^<(\w+)(\s+(\w+)\s*\=\s*('|")(.*?)\4\s*)*\s*(\/>|>)$ | 19 / 20 | indéterminé |
Implémentation
const re = new RegExp("^<([a-zA-Z][a-zA-Z0-9]*)((?:\\s+[a-zA-Z-]+(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'))?)*)\\s*(\\/)?>$", "");
re.test(input);Limites
- Ne reconnaît qu'UNE balise isolée, jamais un document imbriqué : c'est précisément ce que la réponse la plus votée de tous les temps sur Stack Overflow (4400+ votes) explique en détail — HTML n'est pas un langage régulier, une regex ne peut pas suivre l'imbrication de balises ouvertes/fermées.
- Ne reconnaît pas les balises fermantes (« </p> ») ni les déclarations spéciales (commentaires, DOCTYPE) : un motif séparé est nécessaire pour chacune.
- N'exécute aucune validation sémantique : une balise avec un nom qui n'existe pas en HTML (« <foo> ») ou un attribut invalide pour cet élément passe très bien, car ce n'est pas une question de forme.
- Pour un usage réel sur du HTML produit par un tiers (page web, contenu utilisateur), un vrai parseur HTML/DOM reste la seule option fiable — cette regex convient à un cas contrôlé et limité (ex. extraire une donnée d'un gabarit HTML que tu maîtrises toi-même), pas à du grattage de pages arbitraires.