Усекать текст без обрезания HTML

Эта строка содержит 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 = '&hellip;', $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); 

Функция была схвачена (сделана небольшая модификация):

http://www.dzone.com/snippets/truncate-text-preserving-html