HTML / XML se divide en marcado y contenido. Regex solo es útil haciendo un análisis de etiqueta léxica. Supongo que podrías deducir el contenido. Sería una buena opción para un analizador SAX. Las etiquetas y el contenido se pueden entregar a una función definida por el usuario donde se puede realizar un seguimiento de la anidación / cierre de elementos.
En cuanto al análisis de las etiquetas, puede hacerse con expresiones regulares y usarse para quitar etiquetas de un documento.
Durante años de pruebas, he encontrado el secreto de la forma en que los navegadores analizan las etiquetas, tanto bien como mal formadas.
Los elementos normales se analizan con esta forma:
El núcleo de estas etiquetas usa esta expresión regular
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
Notarás esto [^>]?
como una de las alternancias. Esto coincidirá con citas desequilibradas de etiquetas mal formadas.
También es la raíz más simple de todo mal para las expresiones regulares. La forma en que se usa provocará un golpe para satisfacer su codicioso contenedor cuantificado que debe coincidir.
Si se usa de forma pasiva, nunca hay un problema. Pero, si obliga a que algo coincida al intercalarlo con un par de atributo / valor deseado, y no proporciona la protección adecuada contra el retroceso, es una pesadilla fuera de control.
Esta es la forma general de las etiquetas antiguas simples. Observe que [\w:]
representa el nombre de la etiqueta? En realidad, los caracteres legales que representan el nombre de la etiqueta son una lista increíble de caracteres Unicode.
<
(?:
[\w:]+
\s+
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
\s* /?
)
>
Continuando, también vemos que simplemente no puede buscar una etiqueta específica sin analizar TODAS las etiquetas. Quiero decir que podrías, pero tendría que usar una combinación de verbos como (* SKIP) (* FAIL) pero aún así todas las etiquetas deben analizarse.
La razón es que la sintaxis de la etiqueta puede estar oculta dentro de otras etiquetas, etc.
Por lo tanto, para analizar pasivamente todas las etiquetas, se necesita una expresión regular como la siguiente. Este particular también coincide con contenido invisible .
A medida que nuevos HTML o xml o cualquier otro desarrollen nuevas construcciones, simplemente agréguelo como una de las alternancias.
Nota de la página web: nunca he visto una página web (o xhtml / xml) con la que haya
tenido problemas. Si encuentras uno, házmelo saber.
Nota de rendimiento: es rápido. Este es el analizador de etiquetas más rápido que he visto
(puede haber más rápido, quién sabe).
Tengo varias versiones específicas También es excelente como raspador
(si eres del tipo práctico).
Completa expresión regular cruda
<(?:(?:(?:(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]*?))))>
Aspecto formateado
<
(?:
(?:
(?:
# 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]*? )
)
)
)
>