PHP Regex - Elimina texto entre etiquetas

Tengo esto:

$text = 'text text text s html tagove
<div id="content">ss adsda sdsa </div>
oshte text s html tagove';
$content = preg_replace('/(<div\sid=\"content\">)[^<]+(<\/div>)/i', '', $text);
var_dump($content); 

Pero si el <div id="content"></div> contiene otras etiquetas, como <b>,<i> etc., no funciona.

Por ejemplo:

$text = 'text text text s html tagove
<div id="content"><b> stfu </b> ss adsda sdsa </div>
oshte text s html tagove';

preguntado el 09 de marzo de 12 a las 21:03

¿Qué texto desea eliminar si hay varias etiquetas? -

No analice HTML con expresiones regulares. Usa uno de los analizadores que tienes en PHP. -

No usaría STFU como una ilustración de su necesidad. es una mala palabra -

@MarcelloGrechiLins - Estoy seguro de que Sindicato de Agricultores Inquilinos del Sur podría pensar diferente! ;-)-

2 Respuestas

Puede usar el cuantificadores perezosos en vez.

$s="foo<div>Some content is <b>bold</b>.</div>bar\n";

print preg_replace("/<div>.+?<\/div>/i", "", $s);'

salida:

foobar

ACTUALIZACIÓN por comentarios:

[ghoti@pc ~]$ cat doit.php 
<?php

$text = 'text text text s html tagove
<div id="content"><b> stfu </b> ss adsda sdsa </div>
oshte text s html tagove';

print preg_replace('/<div id="content">.+?<\/div>/im', '', $text) .  "\n";

[ghoti@pc ~]$ php doit.php 
text text text s html tagove

oshte text s html tagove
[ghoti@pc ~]$ 

respondido 10 mar '12, 06:03

esto solo coincide con la etiqueta div si no hay atributos como los que tiene en el ejemplo. - jonathan kuhn

Y no funcionará, por ejemplo <div id="content">ss <div>adsda</div> sdsa </div>, -1. No analice HTML con expresiones regulares. - Qimpuesto

@Qtax: no hay nada de malo en analizar HTML con expresiones regulares si tiene una entrada predecible y el problema está dentro del ámbito de lo que puede manejar una expresión regular. El OP estaba preocupado por incrustar , no incrustar s. - ghoti

@JonathanKuhn: este ejemplo pretendía ser una demostración simple de un cuantificador perezoso. Pero está bien, agregaré una corrección al preg_replace original del OP como una actualización. - ghoti

Estoy de acuerdo. Esto funciona y aborda las preocupaciones del OP. Si manejar HTML en RE es una mala idea, tal vez sea un voto negativo para esta pregunta, pero no para la respuesta. - Graham

Es mejor usar DOM para manejar el análisis de texto HTML. Aquí hay un código basado en DOM para eliminar su etiqueta div:

$html = <<< EOF
text text text s html tagove
<div id="content">ss <div>abcd</div>adsda sdsa </div>
oshte text s html tagove
<div id="content">foo <div>bar</div>baz foo</div>
some more text here
EOF;

$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($html);
$xpath = new DOMXPath($doc);
$nlist = $xpath->query("//div[@id='content']");
for($i=0; $i < $nlist->length; $i++) {
   $node = $nlist->item($i);
   $node->parentNode->removeChild($node);
}
$newHTML =  $doc->saveHTML();
echo $newHTML;

Gracias a @Qtax por señalarme que la pregunta original cambió después de que escribí mi respuesta anterior basada en expresiones regulares.

SALIDA:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<p>text text text s html tagove
</p>
oshte text s html tagove

some more text here</body></html>

respondido 10 mar '12, 04:03

@Qtax: Me alegro de que al menos hayas dejado un comentario para votar negativamente. Si puedes decirme un poco más por qué es peor, te lo agradeceré mucho. - anubhava

El código en su respuesta no funciona o ni siquiera intenta resolver el problema en cuestión, lea la pregunta nuevamente. (Pista: tiene problemas con las etiquetas anidadas). - Qimpuesto

Ah mierda, tienes razón. Sin embargo, esta etiqueta anidada no estaba allí originalmente y cuando publiqué esta respuesta. Yo mismo sigo escribiendo en SO sobre varias preguntas para NO usar expresiones regulares para el análisis de HTML (y puede ver mi advertencia en la parte superior de mi respuesta) y ahora volvió a morderme :) - anubhava

@Qtax: edité y publiqué un código basado en DOM para eliminar la etiqueta div. - anubhava

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.