Скажем, у меня есть строка с 200 символами, содержащая разметку HTML. Я хочу показать предварительный просмотр только первых 50 символов. без «расщепления» тегов. Другими словами, фрагмент не должен содержать <b>
без </b>
. Любая обработка на стороне сервера должна быть в PHP.
Вы должны проверить Tidy HTML. Просто отрежьте его после первых 50 символов, отличных от HTML, а затем запустите его через Tidy, чтобы исправить HTML.
Простым подходом может быть strip_tags()
а затем захват выдержки.
Короткий ответ: преобразуйте его в DOM с помощью DOMDocument::loadHTML($string)
затем пройдите дерево, считая символы в текстовых узлах. Когда вы нажмете свой лимит, замените остальную часть этого узла на «…» или пустую строку и просто вызовите $node->parentNode->removeChild($node)
на всех последующих узлах.
Вот быстрое и надежное решение, использующее DOMDocument, который является частью стандартного PHP:
function cut_html ($html, $limit) { $dom = new DOMDocument(); $dom->loadHTML(mb_convert_encoding("<div>{$html}</div>", "HTML-ENTITIES", "UTF-8"), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); cut_html_recursive($dom->documentElement, $limit); return substr($dom->saveHTML($dom->documentElement), 5, -6); } function cut_html_recursive ($element, $limit) { if($limit > 0) { if($element->nodeType == 3) { $limit -= strlen($element->nodeValue); if($limit < 0) { $element->nodeValue = substr($element->nodeValue, 0, strlen($element->nodeValue) + $limit); } } else { for($i = 0; $i < $element->childNodes->length; $i++) { if($limit > 0) { $limit = cut_html_recursive($element->childNodes->item($i), $limit); } else { $element->removeChild($element->childNodes->item($i)); $i--; } } } } return $limit; }