¿Solución final para usar regex para eliminar etiquetas anidadas html del mismo tipo?

He pasado días tratando de encontrar una solución CON regex (antes de que alguien lo diga: sé que debería estar usando la biblioteca de documentos DOM de PHP o algo similar, pero tomemos esto como una pregunta teórica), buscando respuestas y finalmente llegué arriba con lo que mostraré cerca del final de esta pregunta.

Lo que sigue es solo un resumen de muchas cosas que he probado antes.

En primer lugar, lo que quiero decir con etiquetas anidadas del mismo tipo es:

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>

Ahora imagina que quiero eliminar todos los divsy su contenido usando expresiones regulares. Entonces el resultado esperado sería:

Text outside any div
more text outside divs

La primera idea sería hacer coincidir todo. La siguiente expresión regular hace coincidir las etiquetas div con las propiedades (estilo, id, etc.):

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

El problema, por supuesto, es que esto coincidirátodo entre el comienzo de la primera "<div" y la última "</ div>", por lo que también coincidirá con "más texto fuera de divs" (marque aquí:https://regex101.com/r/iR8mY2/1 ), que no es lo que queremos (I) queremos.

Esto podría resolverse utilizando elModificador U (Sin greedy)

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

pero entonces tendremos el problema de tenerMenos de lo que queremos: solo coincidirá desde el primer "<div" hasta elprimero "" (por lo tanto, si eliminamos las coincidencias, además de algunas etiquetas incomparables, aparecerá el texto "¡Estoy atrapado en un div!", que no queremos).

Entonces, encontré una solución que funciona como un encanto para paréntesis anidados, corchetes, etc.

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

Básicamente, lo que esto hace es encontrar un corchete de apertura, luego hacer coincidir cualquier cosa * que no sea un corchete de apertura ni de cierre * O una estructura recursiva de eso, encontrar un corchete de cierre.

Lo que estoy trabajando ahora es una mala solución: básicamente, primero reemplazo todas las etiquetas de apertura con un corchete (que no puede estar en mi código, por otras razones), luego la etiqueta de cierre para un corchete de cierre y luego usa la expresión regular anterior.No es una solución muy elegante, lo sé.

La cosa es que realmente quierosaber cómo se podría hacer esto con solo una expresión regular. Parece obvio que reemplazar en la expresión regular anterior el "[" y el "]" por las etiquetas htmltiene trabajar. Pero no es tan fácil. El problema es la negación de caracteres ("[^ .......]" no funciona para cadenas como "div". Parece que se puede lograr algo similar con esto:

.+?(?=<div>)

y, por supuesto, lo mismo para la etiqueta de cierre

.+?(?=<\/div>

Así es como, más o menos, llegué a esta expresión regular

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

Que funciona exactamente como elprimero regex que presenté antes:https://regex101.com/r/yU8pV3/1

Ésta es mi pregunta:lo que está mal con esa expresión regular?

¡Gracias!

Respuestas a la pregunta(1)

Su respuesta a la pregunta