HTML / XML é dividido em marcação e conteúdo. Regex é útil apenas na análise de tags lexicais. Eu acho que você poderia deduzir o conteúdo. Seria uma boa escolha para um analisador SAX. Tags e conteúdo podem ser entregues a uma função definida pelo usuário, onde o aninhamento / fechamento de elementos pode ser mantido.
Na medida em que apenas analisa as tags, isso pode ser feito com regex e usado para retirar as tags de um documento.
Ao longo de anos de testes, descobri o segredo da maneira como os navegadores analisam as tags, bem e mal formadas.
Os elementos normais são analisados com este formulário:
O núcleo dessas tags usa esse regex
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
Você notará isso [^>]?
como uma das alternâncias. Isso corresponderá a aspas desequilibradas de tags mal formadas.
É também a mais raiz de todos os males às expressões regulares. A maneira como é usada aciona um bump-along para satisfazer seu recipiente quantificado ganancioso e que deve corresponder.
Se usado passivamente, nunca há um problema Mas, se você forçar a correspondência de algo, intercalando-o com um par de atributo / valor desejado e não fornecer proteção adequada contra retorno, é um pesadelo fora de controle.
Essa é a forma geral para tags antigas simples. Observe a [\w:]
representação do nome da tag? Na realidade, os caracteres legais que representam o nome da marca são uma lista incrível de caracteres Unicode.
<
(?:
[\w:]+
\s+
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
\s* /?
)
>
Continuando, também vemos que você não pode procurar uma tag específica sem analisar TODAS as tags. Quero dizer que você poderia, mas teria que usar uma combinação de verbos como (* SKIP) (* FAIL), mas ainda assim todas as tags precisam ser analisadas.
O motivo é que a sintaxe das tags pode estar oculta dentro de outras tags, etc.
Portanto, para analisar passivamente todas as tags, é necessário um regex como o abaixo. Este em particular também combina com conteúdo invisível .
À medida que o novo HTML ou xml ou qualquer outro desenvolver novas construções, adicione-o como uma das alternativas.
Nota da página da Web - nunca vi uma página da Web (ou xhtml / xml) com a qual
havia problemas. Se você encontrar um, me avise.
Nota de desempenho - É rápido. Este é o analisador de tags mais rápido que eu já vi
(pode ser mais rápido, quem sabe).
Eu tenho várias versões específicas. Também é excelente como raspador
(se você é do tipo hands-on).
Regex bruto 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]*?))))>
Aparência formatada
<
(?:
(?:
(?:
# 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]*? )
)
)
)
>