2015-07-17 7 views
5

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:

  1. /<[a-zA-Z][^>]+ - corrisponde l'inizio di ogni tag html e qualsiasi combinazione di tag e attributi all'interno, ma non la staffa fine
  2. (?i:class)=\" - l'inizio di un attributo di classe,-insensitive caso
  3. (?: - iniziare una sub-pattern non cattura
  4. (?: *[a-zA-Z_][\w-]* +)* - qualsiasi numero di CLA nomi ss (o nessuno), ma se esistono, ci devono essere spazi bianchi prima dell'acquisizione
  5. (* .implode ('|', $ classi). *) - l'insieme di classi per catturare, preg_quoted
  6. (?: +[a-zA-Z_][\w-]* *)* - qualsiasi numero di nomi di classe (o nessuno), ma se esistono, ci deve essere spazio bianco dopo la cattura
  7. )+ - chiudere la sotto-regola non-cattura e ciclo in caso di più classi di corrispondenza sono in un attributo
  8. \"(?: [^>]*)>/ - 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?

+0

perché non usare DOM? – Robert

+0

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> "')? –

+0

@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. –

risposta

-1

Questo sostituirà tutte le classi in tutto l'html.

myHtml.replace(/class\=\"[^\"]*\"/g,''); 

È questo quello che stai cercando? O qualcosa di più specifico?

+0

o se c'è un edgecase molto inusuale in cui class = "" non esiste all'interno di un tag si potrebbe fare questo: myHtml.replace (/ (<[^>] *) class \ = \ "[^ \"] * \ "/ g, '$ 1'); –

+0

no, cercando di sostituire solo le classi che appaiono in un determinato elenco, senza cercare tutte le classi –

+0

Whay è l'elenco dato? –

0

Ok, è l'elenco dei nomi di classe che si desidera rimuovere da un determinato html?

ciò che intendo dire è l'elenco di nomi di classi che si desidera rimuovere. Puoi dare un esempio del tipico html, di cosa si tratta e di cosa vuoi cambiarlo. Esempio:

Prima

<div class="someClass"> 
    <i class="dontchange doChange"></i> 
    <a class="hello john"></a> 
</div> 

Scelgo

<div> 
    <i class="dontchange"></i> 
    <a></a> 
</div> 
+0

Intendo popolare l'elenco dei nomi di classe caso per caso, ma saranno un insieme di stringhe letterali che sono stati escapizzati per l'uso nelle espressioni regolari, i nomi delle classi da rimuovere saranno funzionalmente equivalenti a (str1 | str2 | str3). Il tuo esempio è accurato, anche se non è necessario spingermi fino a rimuovere gli attributi di classe vuoti. .. nel peggiore dei casi, potrei pulirli con uno str_replac e, dopo il fatto –

Problemi correlati