Endgültige Lösung für die Verwendung von Regex zum Entfernen von verschachtelten HTML-Tags desselben Typs?

Ich habe tagelang versucht, eine Lösung MIT Regex zu finden (bevor es jemand sagt: Ich weiß, dass ich die PHP-DOM-Dokumentbibliothek oder etwas Ähnliches verwenden sollte, aber nehmen wir dies als theoretische Frage), nach Antworten gesucht und schließlich kam mit, was ich gegen Ende dieser Frage zeigen werde.

Was folgt, ist nur eine Zusammenfassung vieler Dinge, die ich zuvor ausprobiert habe.

Zunächst meine ich mit verschachtelten Tags des gleichen Typs:

Text outside any div
<div id="my_id"> bla bla
  <div>
  bla bla bla
    <div style="some style here">
      lalalalala
     </div>
   </div>
    I'm trapped in a div!
</div>
more text outside divs

<div>more divs here!
       <div id="justbeingannoying">radiohead rules</div>
</div>

Jetzt stell dir vor, ich möchte alle divs entfernenund deren Inhalt Regex verwenden. Das beabsichtigte Ergebnis wäre also:

Text outside any div
more text outside divs

Die erste Idee würde zu allem passen. Der folgende reguläre Ausdruck vergleicht div-Tags mit Eigenschaften (Stil, ID usw.):

/<div[^>]*>.*<\/div>/sig

Das Problem ist natürlich, dass dies mit @ übereinstimalle zwischen dem Anfang des ersten "<div" und dem letzten "</ div>", damit es auch mit "mehr Text außerhalb von divs" übereinstimmt (siehe hier:https: //regex101.com/r/iR8mY2/), was nicht wollen wir (ich) wollen.

Dies könnte mit dem @ gelöst werdU Modifikator (Ungreedy)

/<div[^>]*>.*<\/div>/sigU

Aber dann haben wir das Problem mitwenige als wir wollen: es wird nur vom ersten "<div" bis zum @ passzuers "" (Wenn wir also die Übereinstimmungen entfernen, wird neben einigen nicht übereinstimmenden Tags der Text "Ich bin in einem Div gefangen!" angezeigt, den wir nicht möchten.)

Also, ich habe eine Lösung gefunden, die wie ein Zauber für verschachtelte Klammern, eckige Klammern usw. funktioniert:

/\[([^\[\]]*+|(?R))*\]/si

rundsätzlich bedeutet dies, eine öffnende eckige Klammer zu finden und dann alles zu finden, was weder eine öffnende noch eine schließende eckige Klammer ist, ODER eine rekursive Struktur davon, nämlich eine schließende eckige Klamme

Was ich jetzt arbeiten muss, ist eine schlechte Lösung: Im Grunde ersetze ich zuerst alle öffnenden Tags durch eine eckige Klammer (die aus anderen Gründen nicht in meinem Code enthalten ist), dann das schließende Tag für eine schließende eckige Klammer und dann Ich benutze den vorherigen regulären Ausdruck. Keine sehr elegante Lösung, ich weiß.

Die Sache ist, ich möchte wirklichkenn wie das mit nur einem regulären Ausdruck gemacht werden kann. Es ist naheliegend, in der vorherigen Regex das "[" und das "]" durch die HTML-Tags @ zu ersetzeha arbeiten. Ist aber nicht so einfach. Das Problem ist die Negation für Zeichen ("[^ .......]" funktioniert nicht für Zeichenfolgen wie "div". Es scheint, dass etwas Ähnliches dadurch erreicht werden kann:

.+?(?=<div>)

und natürlich das gleiche für das schließende Tag

.+?(?=<\/div>

Dies ist, wie ich mehr oder weniger zu diesem Regex gekommen bin

/<div((.+?(?=<\/div>)|.+?(?=<div>))|(?R))*<\/div>/gis

Was genau wie das @ funktioniezuers Regex, den ich zuvor vorgestellt habe:https: //regex101.com/r/yU8pV3/

Also, hier ist meine Frage:was ist falsch mit diesem Regex?

Vielen Dank

Antworten auf die Frage(2)

Ihre Antwort auf die Frage