Come posso rimuovere un intero tag HTML (e il suo contenuto) dalla sua classe utilizzando una regex?

StackOverflow https://stackoverflow.com/questions/226562

  •  03-07-2019
  •  | 
  •  

Domanda

Non sono molto bravo con Regex ma sto imparando.

Vorrei rimuovere alcuni tag html dal nome della classe.Questo è quello che ho finora:

<div class="footer".*?>(.*?)</div>

Il primo .*?è perché potrebbe contenere altri attributi e il secondo è che potrebbe contenere altro materiale HTML.

Che cosa sto facendo di sbagliato?Ho provato molti set senza successo.

Aggiornamento

All'interno del DIV può contenere più righe e sto giocando con Perl regex.

È stato utile?

Soluzione

Dovrai anche consentire altre cose prima della lezione nel tag div

<div[^>]*class="footer"[^>]*>(.*?)</div>

Inoltre, fai distinzione tra maiuscole e minuscole. Potrebbe essere necessario sfuggire a cose come le virgolette o la barra nel tag di chiusura. In quale contesto lo stai facendo?

Si noti inoltre che l'analisi HTML con espressioni regolari può essere molto sgradevole, a seconda dell'input. Un buon punto è riportato in una risposta di seguito - supponi di avere una struttura come:

<div>
    <div class="footer">
        <div>Hi!</div>
    </div>
</div>

Cercare di creare una regex per questo è una ricetta per il disastro. La soluzione migliore è caricare il documento in un DOM ed eseguire manipolazioni su di esso.

Pseudocodice che dovrebbe essere strettamente associato a XML :: DOM:

document = //load document
divs = document.getElementsByTagName("div");
for(div in divs) {
    if(div.getAttributes["class"] == "footer") {
        parent = div.getParent();
        for(child in div.getChildren()) {
            // filter attribute types?
            parent.insertBefore(div, child);
        }
        parent.removeChild(div);
    }
}


Ecco una libreria perl, HTML :: DOM , e un'altra, XML :: DOM
.NET ha librerie integrate per gestire l'analisi dom.

Altri suggerimenti

Come hanno detto altre persone, l'HTML è notoriamente complicato da gestire con l'utilizzo delle regex e un approccio DOM potrebbe essere migliore. Per esempio:.

use HTML::TreeBuilder::XPath;

my $tree = HTML::TreeBuilder::XPath->new;
$tree->parse_file( 'yourdocument.html' );

for my $node ( $tree->findnodes( '//*[@class="footer"]' ) ) {
    $node->replace_with_content;   # delete element, but not the children
}

print $tree->as_HTML;

In Perl hai bisogno di /s modificatore, altrimenti il ​​punto non corrisponderà a una nuova riga.

Detto questo, utilizzare un parser HTML o XML adeguato per rimuovere parti indesiderate di un file HTML è molto più appropriato.

<div[^>]*class="footer"[^>]*>(.*?)</div>

Ha funzionato per me, ma era necessario utilizzare barre rovesciate prima dei caratteri speciali

<div[^>]*class=\"footer\"[^>]*>(.*?)<\/div>

Dipende in parte dall'esatto motore regex che stai usando - quale lingua ecc. Ma una possibilità è che devi evitare le virgolette e / o la barra. Potresti anche renderlo insensibile alle maiuscole.

<div class=\"footer\".*?>(.*?)<\/div>

Altrimenti, specifica la lingua / la piattaforma che stai utilizzando: .NET, java, perl ...

Prova questo:

<([^\s]+).*?class="footer".*?>([.\n]*?)</([^\s]+)>

Il tuo problema più grande saranno i tag nidificati. Ad esempio:

<div class="footer"><b></b></div>

La regexp fornita corrisponderebbe a tutto attraverso </b>, lasciando </div> alla fine. Dovrai supporre che il tag che stai cercando non abbia elementi nidificati, oppure dovrai usare una sorta di parser da HTML a DOM e una query XPath per rimuovere un intero sotto-albero.

Questo sarà complicato a causa dell'avidità delle espressioni regolari, (Nota che i miei esempi possono sono specifici del perl, ma so che l'avidità è un problema generale con le RE.) Il secondo . *? corrisponderà il più possibile prima di < / div > , quindi se disponi di quanto segue:

< div class = " SomethingElse " > < div class = " footer " > cose < / div > < / div >

L'espressione corrisponderà:

< div class = " footer " > cose < / div > < / div >

che non è probabilmente quello che vuoi.

perché non < div class = " footer ". *? < / div > Non sono neanche un guru regex, ma non penso che tu debba specificare l'ultimo parentesi per il tag div aperto

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top