Concordo sul fatto che lo strumento giusto per analizzare XML e soprattutto HTML sia un parser e non un motore di espressione regolare. Tuttavia, come altri hanno sottolineato, a volte l'uso di una regex è più veloce, più facile e fa il lavoro se si conosce il formato dei dati.
Microsoft ha in realtà una sezione di Best practice per le espressioni regolari in .NET Framework e parla in particolare di Considerare [ing] l'origine di input .
Le espressioni regolari hanno dei limiti, ma hai considerato quanto segue?
Il framework .NET è unico quando si tratta di espressioni regolari in quanto supporta le definizioni dei gruppi di bilanciamento .
Per questo motivo, credo che PUOI analizzare XML usando espressioni regolari. Si noti tuttavia che deve essere un XML valido (i browser perdonano molto l'HTML e consentono una sintassi XML errata all'interno dell'HTML ). Ciò è possibile poiché la "Definizione del gruppo di bilanciamento" consentirà al motore di espressione regolare di fungere da PDA.
Citazione dall'articolo 1 sopra citato:
Motore di espressioni regolari .NET
Come descritto sopra, i costrutti correttamente bilanciati non possono essere descritti da un'espressione regolare. Tuttavia, il motore di espressione regolare .NET fornisce alcuni costrutti che consentono il riconoscimento di costrutti bilanciati.
(?<group>)
- inserisce il risultato acquisito nello stack di acquisizione con il gruppo di nomi.
(?<-group>)
- fa apparire la parte più alta dell'acquisizione con il gruppo di nomi dallo stack di acquisizione.
(?(group)yes|no)
- corrisponde alla parte sì se esiste un gruppo con il gruppo nome altrimenti non corrisponde alcuna parte.
Questi costrutti consentono a un'espressione regolare .NET di emulare un PDA limitato, essenzialmente consentendo versioni semplici delle operazioni dello stack: push, pop e empty. Le semplici operazioni sono praticamente equivalenti a incremento, decremento e confronto rispettivamente a zero. Ciò consente al motore di espressione regolare .NET di riconoscere un sottoinsieme dei linguaggi senza contesto, in particolare quelli che richiedono solo un semplice contatore. Ciò a sua volta consente alle espressioni regolari .NET non tradizionali di riconoscere singoli costrutti correttamente bilanciati.
Considera la seguente espressione regolare:
(?=<ul\s+id="matchMe"\s+type="square"\s*>)
(?>
<!-- .*? --> |
<[^>]*/> |
(?<opentag><(?!/)[^>]*[^/]>) |
(?<-opentag></[^>]*[^/]>) |
[^<>]*
)*
(?(opentag)(?!))
Usa le bandiere:
- Linea singola
- IgnorePatternWhitespace (non necessario se si comprime regex e si rimuove tutto lo spazio bianco)
- IgnoreCase (non necessario)
Spiegazione delle espressioni regolari (in linea)
(?=<ul\s+id="matchMe"\s+type="square"\s*>) # match start with <ul id="matchMe"...
(?> # atomic group / don't backtrack (faster)
<!-- .*? --> | # match xml / html comment
<[^>]*/> | # self closing tag
(?<opentag><(?!/)[^>]*[^/]>) | # push opening xml tag
(?<-opentag></[^>]*[^/]>) | # pop closing xml tag
[^<>]* # something between tags
)* # match as many xml tags as possible
(?(opentag)(?!)) # ensure no 'opentag' groups are on stack
Puoi provarlo su A Better .NET Regular Expression Tester .
Ho usato la fonte di esempio di:
<html>
<body>
<div>
<br />
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
</div>
</body>
</html>
Questo ha trovato la corrispondenza:
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
anche se in realtà è uscito così:
<ul id="matchMe" type="square"> <li>stuff...</li> <li>more stuff</li> <li> <div> <span>still more</span> <ul> <li>Another >ul<, oh my!</li> <li>...</li> </ul> </div> </li> </ul>
Infine, mi è piaciuto molto l'articolo di Jeff Atwood: Parsing Html The Cthulhu Way . Abbastanza divertente, cita la risposta a questa domanda che attualmente ha oltre 4k voti.