Поддержка Проблемы и решения удаление содержимого тега

  • для удаления тега вместе с содержимым я всегда пользовался функцией strip_tags_content (первая функция в User Contributed Notes).

    однако, как оказалось — она не справляется со вложенностью.
    то есть обрабатывая код аля:

    
    <div>
    <div>тест</div>
    </div>
    

    получаем результат:

    
    </div>
    

    я так понимаю, что функция останавливается на первом вхождении закрывающего тега. переделывать функцию не вариант — разбираться в чужих регулярках та еще морока.

    поэтому вопрос — никто не сталкивался с кодом\функцией удаления указанного тега вместе с контентом и без глюков со вложенностью? гугл я замучил, но ничего толком не нашел. dom-парсер разбивается о некорректный код и толком не пашет.

Просмотр 6 ответов — с 1 по 6 (всего 6)
  • Модератор Sergey Biryukov

    (@sergeybiryukov)

    Live and Learn

    переделывать функцию не вариант

    У меня вроде получилось поправить регулярки и переделать в рекурсивную функцию:

    
    function strip_tags_content( $text, $tags = '', $invert = false ) {
    	preg_match_all( '/<(.+?)[\s]*\/?[\s]*>/si', trim( $tags ), $tags_array );
    	$tags_array = array_unique( $tags_array[1] );
    
    	$regex = '';
    
    	if ( count( $tags_array ) > 0 ) {
    		if ( ! $invert ) {
    			$regex = '@<(?!(?:' . implode( '|', $tags_array ) . ')\b)(\w+)\b[^>]*?(>((?!<\1\b).)*?<\/\1|\/)>@si';
    			$text  = preg_replace( $regex, '', $text );
    		} else {
    			$regex = '@<(' . implode( '|', $tags_array ) . ')\b[^>]*?(>((?!<\1\b).)*?<\/\1|\/)>@si';
    			$text  = preg_replace( $regex, '', $text );
    		}
    	} elseif ( ! $invert ) {
    		$regex = '@<(\w+)\b[^>]*?(>((?!<\1\b).)*?<\/\1|\/)>@si';
    		$text  = preg_replace( $regex, '', $text );
    	}
    
    	if ( $regex && preg_match( $regex, $text ) ) {
    		$text = strip_tags_content( $text, $tags, $invert );
    	}
    
    	return $text;
    }
    

    не, Сергей, эта функция тоже не справляется.
    вот пример кода, с котором оно не работает:

    
    <div style="background-image: url('https://site.ru/wp-content/plugins/pdf-light-viewer/assets/img/lightpaperfibers.png');">
    <div class="gradient"></div>
    <img class="js-pdf-light-viewer-lazy-loading js-pdf-light-viewer-lazy-loading-2 initially-hidden" src="https://site/wp-content/plugins/pdf-light-viewer/assets/img/lightpaperfibers.png" width="100%" height="100%" data-original="https://site.ru/wp-content/uploads/pdf-light-viewer/2835/page-00002.jpg" />
    
    </div>
    

    код реальный, из плагина pdf-light-viewer — это я не из вредности замысловатый код сделал.

    Модератор Sergey Biryukov

    (@sergeybiryukov)

    Live and Learn

    код реальный

    С реального кода и надо начинать 🙂 Поправил ещё немного, в исходной функции не учитывались одиночные теги типа <img />.

    все равно не работает.

    
    $text = '
    тест до
    <div style="background-image: url(\'https://site.ru/wp-content/plugins/pdf-light-viewer/assets/img/lightpaperfibers.png\');">
    <div class="gradient"></div>
    <img class="js-pdf-light-viewer-lazy-loading js-pdf-light-viewer-lazy-loading-2 initially-hidden" src="https://site/wp-content/plugins/pdf-light-viewer/assets/img/lightpaperfibers.png" width="100%" height="100%" data-original="https://site.ru/wp-content/uploads/pdf-light-viewer/2835/page-00002.jpg" />
    
    </div>
    тест после
    ';
    
    $text = strip_tags_content( $text, '<div>', true );
    echo $text;
    

    результат:

    
    тест до
    <div style="background-image: url('https://site.ru/wp-content/plugins/pdf-light-viewer/assets/img/lightpaperfibers.png');">
    
    <img class="js-pdf-light-viewer-lazy-loading js-pdf-light-viewer-lazy-loading-2 initially-hidden" src="https://site/wp-content/plugins/pdf-light-viewer/assets/img/lightpaperfibers.png" width="100%" height="100%" data-original="https://site.ru/wp-content/uploads/pdf-light-viewer/2835/page-00002.jpg" />
    
    </div>
    тест после
    

    вырезался только div в середине.

    Модератор Sergey Biryukov

    (@sergeybiryukov)

    Live and Learn

    Поправил ещё немного, теперь и $invert работает 🙂

    Но вообще тут же в родительском <div> нет контента помимо других тегов, то есть по идее и strip_tags() было бы достаточно?

    то есть по идее и strip_tags() было бы достаточно?

    не, я обрабатываю весь контент записи (не только вывод плагина) и надо удалить лишнее (плагин RSS for Yandex Turbo), оставив все не лишнее. на сайте pdf-light-viewer выводит листалку pdf, а вот в яндекс.турбо, где нет скриптов эта листалка превращается в туеву кучу картинок друг за другом, которые еще и не укладывается в лимиты яндекса (там 30 картинок на item).

    так что огромное спасибо Сергей, все работает.
    сам бы я точно с регулярками не справился.

Просмотр 6 ответов — с 1 по 6 (всего 6)
  • Тема «удаление содержимого тега» закрыта для новых ответов.