Мне нужна помощь, удаляющая пустые теги в моем HTML. Здесь есть решение:
Удаление пустых тегов с помощью RegEx
Но я не могу использовать JS, и я никогда не должен использовать регулярные выражения для синтаксического анализа HTML .
Мне нужно очистить входы с помощью PHP, и мне также нужно получить больше, чем просто пустые теги.
Мне также нужно поймать теги следующим образом:
<p> </p> (variable whitespace with nothing in the tag) <p> </p> <p><br/><p> <p><br /></p>
Что я могу сделать, чтобы поймать плохую разметку, прежде чем она попадет в базу данных (WYSIWYG)?
Разберите его с парсером модели объекта документа , проверьте текстовое содержимое узлов, удалите узлы, которые не соответствуют вашим критериям (синтаксический анализ как тег сценария, содержит пробелы, является iframe и т. Д.).
Довольно много примеров кода в разделе комментариев.
Вот куча кода, который делает что-то вроде этого (принятое из случайного вырезания + вставка на php.net)
<?php $sampleHTML = " <p> </p> <p> <p> <p><br/></p> <p><br /></p> <span>Non-empty span<p id='NestedEmptyElement'></p></span> "; $doc = new DOMDocument(); $doc->loadHTML($sampleHTML); $domNodeList = $doc->getElementsByTagname('*'); $domElemsToRemove = array(); foreach ( $domNodeList as $domElement ) { $domElement->normalize(); if (trim($domElement->textContent, "\xc2\xa0 \n \t ") == "") { $domElemsToRemove[] = $domElement; } } foreach( $domElemsToRemove as $domElement ){ try { $domElement->parentNode->removeChild($domElement); } catch (Exception $e) { //node was already deleted. //There's a better way to do this, it's recursive. } } $domNodeList = $doc->getElementsByTagname('body')->item(0); $childNodes = $domNodeList->childNodes; foreach ( $childNodes as $domElement ) { echo trim($domElement->C14N()); } echo "\n\n";
Тогда мы бежим ..
$ php foo.php -v <span>Non-empty span</span>
Это соответствует вашим примерам и немного больше:
^<p>\s*(?:(?: |<br\s*/>)\s*)*</p>$
Но вы ищете только теги p
? Может ли быть несколько строк?
Еще одно использование normal* (special normal*)*
с:
\s
, ( |<br\s*/>)
(с группами, не связанными с захватом)
Я работал над этим около дня и видел много «не использую регулярное выражение», с которым я согласен.
Тем не менее, у меня были огромные проблемы с DOMDocument, связанным с моими объектами html. Я бы тщательно фильтровал текст, чтобы все символы ТМ были преобразованы в объекты HTML, такие как & trade; но он преобразует их обратно в символ TM.
Я боролся с предотвращением такого поведения в течение некоторого времени. Для этого были некоторые хаки. После дня битвы я подумал: «Почему я должен так много работать, чтобы взломать его на работу? Он должен просто работать». Затем я написал эту функцию, используя simplehtmldom, как 10 минут:
function stripEmptyTags($html){ $dom = new simple_html_dom(); $dom->load($html); foreach($dom->find("*") as $e) if( trim( str_replace( array(' ',' '), "", $e->innertext )) == "" ) $e->outertext = ""; $dom->load($dom->save()); return $dom->save(); }