Я пытаюсь удалить элемент 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>
Я очень ценю любую помощь, я уверен, что есть более простой способ добиться этого, я просто не совсем уверен, почему мой текущий метод не работает, спасибо.
Используйте методы DOM, чтобы найти и удалить <div>
. Также прочтите эта поучительная история о жутких ужасах
Итак, вам нужен только первый текстовый узел coincodex-content
?
Проблема 1: у вас есть несколько тегов </div>
в вашем коде, поэтому ваше регулярное выражение .*
не будет распространяться на последний </div>
во входных данных. Проблема 2: почему #
?
@Nic3500 Nic3500 Вы можете использовать любой символ для разделителя регулярных выражений в PHP, поэтому часто бывает удобно выбрать тот, который не будет отображаться в шаблоне, чтобы избежать дополнительного экранирования.
Это немного обманывает. Основная проблема с использованием регулярных выражений для анализа 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.
С чего начать? Вероятно, было бы лучше не использовать регулярное выражение и анализировать только те данные, которые вы хотите.