HTML / XML è diviso in markup e contenuto. Regex è utile solo per eseguire un'analisi tag lessicale. Immagino che tu possa dedurre il contenuto. Sarebbe una buona scelta per un parser SAX. Tag e contenuti potrebbero essere consegnati a una funzione definita dall'utente in cui è possibile tenere traccia di annidamento / chiusura di elementi.
Per quanto riguarda solo l'analisi dei tag, può essere fatto con regex e utilizzato per rimuovere i tag da un documento.
Nel corso di anni di test, ho scoperto il segreto del modo in cui i browser analizzano i tag, sia in forma che in forma.
Gli elementi normali vengono analizzati con questo modulo:
Il nucleo di questi tag usa questa regex
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
Noterai questo [^>]?
come una delle alternative. Ciò corrisponderà a virgolette non bilanciate da tag mal formati.
È anche la singola radice più cattiva di tutte le espressioni regolari. Il modo in cui viene utilizzato attiverà un bump-along per soddisfare il suo contenitore quantificato avido, da abbinare.
Se usato passivamente, non c'è mai un problema. Ma se costringi qualcosa a corrispondere intervallandolo con una coppia di attributo / valore desiderata e non fornisci una protezione adeguata dal backtracking, è un incubo fuori controllo.
Questa è la forma generale per semplici tag vecchi. Notare che [\w:]
rappresenta il nome del tag? In realtà, i caratteri legali che rappresentano il nome del tag sono un incredibile elenco di caratteri Unicode.
<
(?:
[\w:]+
\s+
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
\s* /?
)
>
Andando avanti, vediamo anche che non puoi semplicemente cercare un tag specifico senza analizzare TUTTI i tag. Voglio dire, potresti, ma dovrebbe usare una combinazione di verbi come (* SKIP) (* FAIL) ma tutti i tag devono essere analizzati.
Il motivo è che la sintassi dei tag può essere nascosta all'interno di altri tag, ecc.
Quindi, per analizzare passivamente tutti i tag, è necessaria una regex come quella qui sotto. Questo particolare corrisponde anche a contenuti invisibili .
Man mano che nuovi HTML o xml o altri sviluppano nuovi costrutti, basta aggiungerlo come una delle alternative.
Nota sulla pagina Web: non ho mai visto una pagina Web (o xhtml / xml) con cui questo ha
avuto problemi. Se ne trovi uno, fammelo sapere.
Nota sulle prestazioni: è veloce. Questo è il parser tag più veloce che abbia mai visto
(potrebbe esserci più veloce, chissà).
Ho diverse versioni specifiche. È anche eccellente come raschietto
(se sei il tipo pratico).
Regex grezzo completo
<(?:(?:(?:(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]*?))))>
Aspetto formattato
<
(?:
(?:
(?:
# 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]*? )
)
)
)
>