HTML / XML est divisé en balisage et contenu. Regex n'est utile que pour effectuer une analyse de balise lexicale. Je suppose que vous pouvez en déduire le contenu. Ce serait un bon choix pour un analyseur SAX. Les balises et le contenu peuvent être fournis à une fonction définie par l'utilisateur où l'imbrication / fermeture des éléments peut être conservée.
En ce qui concerne simplement l'analyse des balises, cela peut être fait avec regex et utilisé pour retirer les balises d'un document.
Au fil des années de tests, j'ai trouvé le secret de la façon dont les navigateurs analysent les balises, bien ou mal formées.
Les éléments normaux sont analysés avec cette forme:
Le noyau de ces balises utilise cette expression régulière
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
Vous remarquerez cela [^>]?
comme l'une des alternances. Cela correspondra à des citations déséquilibrées de balises mal formées.
C'est aussi la racine la plus simple de tous les maux aux expressions régulières. La façon dont il est utilisé déclenchera un bump-along pour satisfaire son conteneur quantifié gourmand et incontournable.
S'il est utilisé de manière passive, il n'y a jamais de problème Mais, si vous forcez quelque chose à correspondre en l'entrecoupant avec une paire attribut / valeur souhaitée, et ne fournissez pas une protection adéquate contre le retour en arrière, c'est un cauchemar hors de contrôle.
Ceci est la forme générale des anciennes balises. Remarquez le [\w:]
représentant du nom de la balise? En réalité, les caractères légaux représentant le nom de la balise sont une incroyable liste de caractères Unicode.
<
(?:
[\w:]+
\s+
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
\s* /?
)
>
En passant, nous constatons également que vous ne pouvez tout simplement pas rechercher une balise spécifique sans analyser TOUTES les balises. Je veux dire que vous pourriez, mais il faudrait utiliser une combinaison de verbes comme (* SKIP) (* FAIL) mais toujours toutes les balises doivent être analysées.
La raison en est que la syntaxe des balises peut être cachée dans d'autres balises, etc.
Donc, pour analyser passivement toutes les balises, une expression régulière est nécessaire comme celle ci-dessous. Celui-ci correspond également au contenu invisible .
Au fur et à mesure que de nouveaux codes HTML ou xml ou tout autre développent de nouvelles constructions, ajoutez-les simplement comme l'une des alternances.
Remarque sur la page Web - Je n'ai jamais vu de page Web (ou xhtml / xml) avec laquelle cela
a rencontré des problèmes. Si vous en trouvez un, faites-le moi savoir.
Note sur les performances - C'est rapide. C'est l'analyseur de balises le plus rapide que j'ai vu
(il peut y en avoir un plus rapide, qui sait).
J'ai plusieurs versions spécifiques. Il est également excellent comme grattoir
(si vous êtes du type pratique).
Regex brut complet
<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?>"[\S\s]*?"|'[\S\s]*?'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\1\s*(?=>))|(?:/?[\w:]+\s*/?)|(?:[\w:]+\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]?)+\s*/?)|\?[\S\s]*?\?|(?:!(?:(?:DOCTYPE[\S\s]*?)|(?:\[CDATA\[[\S\s]*?\]\])|(?:--[\S\s]*?--)|(?:ATTLIST[\S\s]*?)|(?:ENTITY[\S\s]*?)|(?:ELEMENT[\S\s]*?))))>
Aspect formaté
<
(?:
(?:
(?:
# Invisible content; end tag req'd
( # (1 start)
script
| style
| object
| embed
| applet
| noframes
| noscript
| noembed
) # (1 end)
(?:
\s+
(?>
" [\S\s]*? "
| ' [\S\s]*? '
| (?:
(?! /> )
[^>]
)?
)+
)?
\s* >
)
[\S\s]*? </ \1 \s*
(?= > )
)
| (?: /? [\w:]+ \s* /? )
| (?:
[\w:]+
\s+
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
\s* /?
)
| \? [\S\s]*? \?
| (?:
!
(?:
(?: DOCTYPE [\S\s]*? )
| (?: \[CDATA\[ [\S\s]*? \]\] )
| (?: -- [\S\s]*? -- )
| (?: ATTLIST [\S\s]*? )
| (?: ENTITY [\S\s]*? )
| (?: ELEMENT [\S\s]*? )
)
)
)
>