Эта строка содержит 78 символов с HTML и 39 символов без HTML:
<p>I really like the <a href="http://google.com">Google</a> search engine.</p>
Я хочу обрезать эту строку на основе количества символов, отличных от HTML, поэтому, например, если бы я хотел усечь вышеприведенную строку до 24 символов, результатом будет:
I really like the <a href="http://google.com">Google</a>
Усечение не учитывало html при определении количества отключенных символов, оно учитывало только разделяемое количество. Однако он не оставил открытые HTML-теги.
Хорошо, так это то, что я собрал и, кажется, работает:
function truncate_html($string, $length, $postfix = '…', $isHtml = true) { $string = trim($string); $postfix = (strlen(strip_tags($string)) > $length) ? $postfix : ''; $i = 0; $tags = []; // change to array() if php version < 5.4 if($isHtml) { preg_match_all('/<[^>]+>([^<]*)/', $string, $tagMatches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); foreach($tagMatches as $tagMatch) { if ($tagMatch[0][1] - $i >= $length) { break; } $tag = substr(strtok($tagMatch[0][0], " \t\n\r\0\x0B>"), 1); if ($tag[0] != '/') { $tags[] = $tag; } elseif (end($tags) == substr($tag, 1)) { array_pop($tags); } $i += $tagMatch[1][1] - $tagMatch[0][1]; } } return substr($string, 0, $length = min(strlen($string), $length + $i)) . (count($tags = array_reverse($tags)) ? '</' . implode('></', $tags) . '>' : '') . $postfix; }
Применение:
truncate_html('<p>I really like the <a href="http://google.com">Google</a> search engine.</p>', 24);
Функция была схвачена (сделана небольшая модификация):