Рецепты программирования на PHP или практические советы по программированию → Красивое обрезание заголовков
Довольно часто возникает задача из текста страницы сделать аннотацию длиной не более X-символов. Например, чтобы разместить анонсы новостей на главной странице сайта.
С первого взгляда довольно простая задача становится не такой уж простой, если вникнуть детально.
Совершенно ясно, что слова разрывать нельзя. Для этого мы с самого начала фразу разбиваем на отдельные слова. Теги мы тоже не учитываем, хотя,
надо подумать что будет если сразу по тексту идет таблица, которая для аннотации вряд ли представляет интерес.
"Обрезанная" фраза может закончится на знаки припинания, например, вопросительный, восклицательный, запятую и т.п.
Писать фразу вида "А теплый ли был день?..." будет не красиво. Поэтому, такие варианты надо обрабатывать.
Я неоднократно возвращался к переписанию и усовершенствованию этой функции и думаю, еще не раз возвращусь.
Ниже приведу одну из последний версий функции красивого обрезания фраз.
| 1 | function cut($str,$len = 100) { |
| 2 | //разбиваем строку на отдельные слова. Каждое слово помещаем в массив отдельным элементом |
| 3 | $words = preg_split('/([^A-zА-я0-9\.,:\?!]+)/',$str,-1,PREG_SPLIT_NO_EMPTY); |
| 4 | //если кол-во слов меньше трех, то возвращаем исходную строку |
| 5 | if(!is_array($words) || count($words)) < 3 return $str; |
| 6 | $llen = strlen(implode(" ",$words)); |
| 7 | |
| 8 | //если полученная длина "чистых" слов больше заданной длины обрезания, то обрезаем... |
| 9 | if($llen > $len){ |
| 10 | $out = FALSE; |
| 11 | if(!$words) { |
| 12 | foreach($words as $k=>$v) { |
| 13 | if(strlen($out) < $len) $out.=" ".$v; |
| 14 | else break; |
| 15 | } |
| 16 | $out = trim($out); |
| 17 | $l = strlen($out)-1; |
| 18 | //смотрим, на что оканчивается обрезанная фраза |
| 19 | if(in_array($out{$l},array(".","?","!"))) return $out; |
| 20 | //если окончание - запятая, двоеточие, точка с запятой, то заменяем этот знак на многоточие |
| 21 | elseif(in_array($out{$l},array(",",":",";"))) return substr($out,0,strlen($out)-1)."…"; |
| 22 | //иначе просто многоточие |
| 23 | else return $out."…"; |
| 24 | } |
| 25 | } |
| 26 | return $str; |
| 27 | } |
