Preg replace для удаления div из строки

Я пытаюсь удалить элемент HTML из строки,

У меня есть следующее preg_replace ;

    $body = preg_replace('#<div class = "code-block code-block-12" style = "margin: 8px 0; clear: both;">(.*?)</div>#', '', $body);

Но preg_replace, похоже, не работает;

Вот полный код;

    $html = new DOMDocument();
     @$html->loadHtmlFile($url);
     $xpath = new DOMXPath( $html );
     $nodelist = $xpath->query( '//*[@class = "coincodex-content"]' );
     $body = '';
    foreach ($nodelist as $n){
        $body .= $html->saveHtml($n)."\n";
    } 
    
    $body = preg_replace('#<div class = "code-block code-block-12" style = "margin: 8px 0; clear: both;">(.*?)</div>#', '', $body);
    

Текущий вывод таков;

<div class = "coincodex-content">
hello this is content
<div class = "code-block code-block-12" style = "margin: 8px 0; clear: both;">
<div><center><span style = "font-size:11px; color: gray;"TEST</span></center>
<b>TEST</b><br><br></div></div>
<div class = "rp4wp-related-posts rp4wp-related-post">
    </ul></div><!-- AI CONTENT END 1 -->
<div class = "entry-tags" style = "margin-bottom:15px; font-weight: bold; text-align:center;">Tags: <a href = "#" rel = "tag">test</a> <a href = "#" rel = "tag">#tag</a></div>
</div>

И мой желаемый результат ;

<div class = "coincodex-content">
hello this is content
</div>

Я очень ценю любую помощь, я уверен, что есть более простой способ добиться этого, я просто не совсем уверен, почему мой текущий метод не работает, спасибо.

С чего начать? Вероятно, было бы лучше не использовать регулярное выражение и анализировать только те данные, которые вы хотите.

user3783243 29.03.2022 01:48

Используйте методы DOM, чтобы найти и удалить <div>. Также прочтите эта поучительная история о жутких ужасах

Phil 29.03.2022 01:49

Итак, вам нужен только первый текстовый узел coincodex-content?

user3783243 29.03.2022 01:50

Проблема 1: у вас есть несколько тегов </div> в вашем коде, поэтому ваше регулярное выражение .* не будет распространяться на последний </div> во входных данных. Проблема 2: почему # ?

Nic3500 29.03.2022 01:57

@Nic3500 Nic3500 Вы можете использовать любой символ для разделителя регулярных выражений в PHP, поэтому часто бывает удобно выбрать тот, который не будет отображаться в шаблоне, чтобы избежать дополнительного экранирования.

Phil 29.03.2022 01:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
5
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это немного обманывает. Основная проблема с использованием регулярных выражений для анализа HTML — это вложенные теги, которые сведут вас с ума. Если вам действительно нужно сохранить только первый <div> и контент, который появляется перед вторым <div>, ниже будет работать.

preg_match('#<div class = "coincodex-content">(.*)<div.*$#Us', $body, $matches);
$body = '<div class = "coincodex-content">' . $matches[1] . '</div>';

... поскольку мы просто извлекаем нужный нам контент и вставляем его в статический формат контента.

Грязный

Регулярные выражения не подходят для изменения элементов DOM. Ваш эксперимент это показывает. Результат неверный, а также недопустимый HTML.

Вы можете лучше использовать методы DOM для решения проблемы, как указано в комментарии. В DOM есть метод DOMNode::removeChild, который можно использовать для удаления элементов. Чтобы показать, как можно использовать removeChild, я выбрал более простой HTML.

$html = <<<HTML
<div>
<div class = "coincodex-content">
hello this is content
  <div class = "delete_this" style = "margin: 8px 0; clear: both;">
    <div>
       <center><span style = "font-size:11px; color: gray;">TEST</span></center>
       <b>TEST</b><br><br>
     </div>
  </div>
  <div class = "preserved">
    Test2
  </div>
</div>
</div>
HTML;

Собираю фрагменты в массив.

$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXPath($doc);
$nodelist = $xpath->query( '//*[@class = "coincodex-content"]' );

$fragment = [];
foreach($nodelist as $contentNode){
  $removeNodelist = $xpath->query('//div[@class = "delete_this"]',$contentNode); 
  $item = $removeNodelist->item(0);  //only first
  $item->parentNode->removeChild($item); 
  $fragment[] = $doc->saveHTML($contentNode); 
}

Результат во фрагменте [0] :

<div class = "coincodex-content">
hello this is content
  
  <div class = "preserved">
    Test2
  </div>
</div>

Попробуйте сами на 3v4l.org.

Другие вопросы по теме