Данная функция позволит обрезать строку по указанному кол-ву слов с учетом тегов. Все открытые теги будут закрыты после обрезки текста.
PHP:
// урезание строк по словам с учетом тегов
function maxsite_str_word($html, $counttext = 10, $sep = ' ') {
$string = str_replace(" ", ' ', $html);
$string = str_replace(array("\n", "\r", " "), ' ', $string);
$string = str_replace(" ", ' ', $string);
$words = explode($sep, strip_tags($string));
//$counttext++;
if (count($words) < $counttext)
return $string;
$count = mb_strlen(str_replace(" ", '', join($sep, array_slice($words, 0, $counttext))));
$result = '';
$counter_plus = true;
$counter = 0;
$string = iconv('UTF-8', 'CP1251//TRANSLIT//IGNORE', $string);
$string_len = strlen($string);
for($i=0; $i<$string_len; ++$i){
$char = $string[$i];
if($char == '<') $counter_plus = false;
if($char == '>' && $string[$i+1] != '<'){
$counter_plus = true;
$counter--;
}
$result .= $char;
if($counter_plus) $counter++;
if($counter >= $count) {
$pos_space = strpos($string, $sep, $i);
$pos_tag = strpos($string, '<', $i);
if ($pos_space == false) {
$pos = strrpos($result, $sep);
$result = substr($result, 0, strlen($result)-($i-$pos+1));
} else {
$pos = $pos_tag?min($pos_space, $pos_tag):$pos_space;
if ($pos != $i) {
$dop_str = substr($string, $i+1, $pos-$i-1);
$result .= $dop_str;
} else
$result = substr($result, 0, strlen($result)-1);
}
break;
}
}
$result = $result ? iconv('cp1251', 'UTF-8', $result) : $html;
if(!empty($umlauts))
foreach(current($umlauts) as $umlaut)
$result = preg_replace("/~/", $umlaut, $result, 1);
return closetags(trim($result, " .,!?:-/"));
}
// закрытие открытых тегов
function closetags($html){
if (!$html) return '';
if (function_exists("tidy_parse_string")){
$tidy = tidy_parse_string($html, array(
'show-body-only' => true,
), 'UTF8');
$tidy->cleanRepair();
$html = $tidy->value;
return $html;
}
preg_match_all('#<(?!meta|img|br|hr|input\b)\b([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
$openedtags = $result[1];
preg_match_all('#</([a-z]+)>#iU', $html, $result);
$closedtags = $result[1];
$len_opened = count($openedtags);
if (count($closedtags) == $len_opened) return $html;
$openedtags = array_reverse($openedtags);
for ($i=0; $i < $len_opened; $i++) {
if (!in_array($openedtags[$i], $closedtags)) $html .= '</'.$openedtags[$i].'>';
else unset($closedtags[array_search($openedtags[$i], $closedtags)]);
}
return $html;
}
Пример использования:
echo maxsite_str_word('урезание строк <b>по словам с учетом</b> тегов', 4);
// урезание строк <b>по словам</b>