Как обрезать фрагменты HTML, не разбивая теги? - PullRequest
3 голосов
/ 21 января 2010

Скажем, у меня есть строка из 200 символов, которая содержит разметку HTML. Я хочу показать предварительный просмотр только первых 50 символов. без «разделения» тегов. Другими словами, фрагмент не должен содержать <b> без </b>. Любая обработка на стороне сервера должна выполняться на PHP.

Ответы [ 4 ]

3 голосов
/ 21 января 2010

Вы должны проверить Tidy HTML. Просто обрежьте его после первых 50 символов, отличных от HTML, а затем запустите его через Tidy, чтобы исправить HTML.

0 голосов
/ 18 февраля 2016

Вот быстрое и надежное решение с использованием 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;
}
0 голосов
/ 21 января 2010

Краткий ответ: преобразуйте его в DOM с помощью DOMDocument::loadHTML($string), затем пройдитесь по дереву, считая символы в текстовых узлах. Когда вы достигнете своего предела, замените оставшуюся часть этого узла на «...» или пустую строку и просто вызовите $node->parentNode->removeChild($node) на всех последующих узлах.

0 голосов
/ 21 января 2010

Простым подходом может быть сначала strip_tags(), а затем получить отрывок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...