L'HTML viene eseguito prima attraverso un purificatore (tinyMCE + Wordpress), quindi dovrebbe corrispondere a forme un po 'standard. tutti i tag di script e di stile vengono eliminati e tutti i dati all'interno dei tag sono codificati in html, quindi non ci sono simboli estranei di cui preoccuparsi.Ho bisogno di rimuovere rapidamente un set di classi da una stringa arbitraria di html
So che la posizione generale su parsing html con espressioni regolari è "do not", ma in questo specifico esempio, il problema sembra meno simile all'analisi e più simile alla semplice elaborazione delle stringhe ... mi manca un livello invisibile di complessità?
Per quanto posso rompere il basso, sembra che il modello in questione può essere suddiviso in componenti logici:
/<[a-zA-Z][^>]+
- corrisponde l'inizio di ogni tag html e qualsiasi combinazione di tag e attributi all'interno, ma non la staffa fine(?i:class)=\"
- l'inizio di un attributo di classe,-insensitive caso(?:
- iniziare una sub-pattern non cattura(?: *[a-zA-Z_][\w-]* +)*
- qualsiasi numero di CLA nomi ss (o nessuno), ma se esistono, ci devono essere spazi bianchi prima dell'acquisizione(*
.implode ('|', $ classi).*)
- l'insieme di classi per catturare, preg_quoted(?: +[a-zA-Z_][\w-]* *)*
- qualsiasi numero di nomi di classe (o nessuno), ma se esistono, ci deve essere spazio bianco dopo la cattura)+
- chiudere la sotto-regola non-cattura e ciclo in caso di più classi di corrispondenza sono in un attributo\"(?: [^>]*)>/
- alla fine del attributo di classe, e tutto alla fine del tag html
rendendo la regex finale:
$pattern = "/<[a-zA-Z][^>]+ (?i:class)=\"(?:(?: *[a-zA-Z_][\w-]* +)*(*".implode('|', $classes)." *)(?: +[a-zA-Z_][\w-]* *)*)+\"(?: [^>]*)>/";
Non ho ancora provato a eseguire questo, perché so che se funziona, sarò fortemente tentato di usarlo, ma eseguendo questo attraverso un preg_replace
sembra che dovrebbe fare il lavoro, tranne che per un problema minore. Credo che lascerà spazi bianchi estranei attorno all'area di cattura. Questo non è un problema significativo, ma potrebbe essere bello da evitare, se qualcuno sa come.
Va anche notato che questo non è un processo mission-critical, e se la mia cattura di tanto in tanto non riesce a rimuovere le classi, nessuno muore.
quindi, in sostanza ... qualcuno può spiegare che cosa rende questa una cattiva idea in questo caso?
perché non usare DOM? – Robert
La complessità è: l'inizio dell'attributo 'class' può essere abbinato solo a' \ bclass', i nomi di classe possono includere un sacco di cose - ma forse tu * sai cosa stai facendo *, 'preg_quote' funziona se hai caratteri word ai confini, e se no? Cosa succede se '>' non è abilitato ('class =" dd> "')? –
@stribizhev - i casi limite come '>' nel nome classe verrebbero filtrati e rimossi dal disinfettante, prima di arrivare a questo codice, e c'è un'aspettativa piuttosto alta che il codice ricevuto sia stato generato da uno script logico, per avvio. tuttavia, non sono sicuro di seguire il problema con l'attributo della classe ... elaborato? @Robert - Sono preoccupato per la velocità. Questa modifica deve essere eseguita su ogni caricamento della pagina (lo so, ma sono limitato in molti modi) e l'analisi dell'HTML in un oggetto DOM è molto più intensa di memoria/CPU rispetto al motore regex. –