Я использую php и regex для поиска закрытых тегов html в строке:
Это моя строка:
$s="<div><h2>Hello world<h2><p>It's 7Am where I live<p><div>";
Вы можете видеть, что все теги здесь не закрыты.
Я хочу найти все закрытые теги, но проблема в том, что мое регулярное выражение также совпадает с открытыми тегами.
Вот мое регулярное выражение
/<[^>]+>/i
И это моя функция preg_match_all ()
preg_match_all("/<[^>]+>/i",$s,$v); print_r($v);
Что мне нужно изменить в моем регулярном выражении, чтобы соответствовать только закрытым тегам?
<h2> <p> <div>
Вы можете не знать об этом, но DOMDocument
может помочь вам исправить HTML.
$html = "<div><h2>Hello world<h2><p>It's 7Am where I live<p><div>"; libxml_use_internal_errors(true); $dom = new DOMDocument(); $dom->loadHTML('<root>' . $html . '</root>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); $xpath = new DOMXPath($dom); foreach( $xpath->query('//*[not(node())]') as $node ) { $node->parentNode->removeChild($node); } echo substr($dom->saveHTML(), 6, -8);
См. Демонстрацию IDEONE
Результат: <div><h2>Hello world</h2><p>It's 7Am where I live</p></div>
Обратите внимание, что очистка пустого узла на основе XPath необходима, поскольку DOM содержит пустые теги <h2></h2>
, <p></p>
и <div></div>
после загрузки HTML в DOM.
Элемент <root>
добавляется в начале, чтобы убедиться, что мы получаем корневой элемент в порядке. Позже мы можем обработать его с помощью substr
.
LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
Флаги LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
необходимы, чтобы DTD и другие мусор не были добавлены в DOM.
Поиск непревзойденных тегов кажется слишком сложным для регулярного выражения. Вам в основном нужно поместить каждый открывающий тег, который вы видите в очереди, а затем вытащите его из очереди, когда увидите закрывающий тег.
Рекомендуем использовать библиотеку, которая выполняет проверку HTML. См. Следующие вопросы:
Удалить непревзойденные теги HTML в строке
Как найти скрытый тег div
PHP получает все закрытые теги HTML в строке