Привет всем!! Имеется функция обрезки текста по словам: PHP: function my_cut($string, $length){ $string = mb_substr($string, 0, $length,'UTF-8'); // обрезаем и работаем со всеми кодировками и указываем исходную кодировку $position = mb_strrpos($string, ' ', 'UTF-8'); // определение позиции последнего пробела. Именно по нему и разделяем слова $string = mb_substr($string, 0, $position, 'UTF-8'); // Обрезаем переменную по позиции return $string; $text = 'Северная война закончилась в 1721 году'; echo my_cut($text, 17); // выведет 'Северная война', без части слова 'закончилась' она работает только в том случае если $length (значение 17) меньше всех символов в переменной $text. Если у $length значение поменять на 50, например, то выводит только первое слово - "Северная". А нужно, чтоб выводило полностью "Северная война закончилась в 1721 году" Подскажите пожалуйста, как это исправить?
просто добавь в начало функции PHP: if ($length >= mb_strlen($string, 'UTF-8')) { return $string; } и будет выводить фарзу целиком. Повторить вывод только первого слова у меня так и не получилось.
Я использую подобную функцию: PHP: function short_text($text, $len = 200) { $tarr = explode(' ', $text); $txt = ''; $i = 0; while (mb_strlen($txt) < $len && isset($tarr[$i])) { $txt .= $tarr[$i] . ' '; $i++; } return $txt; }
@Maputo то есть допускаешь итоговую строку длиннее чем ограничение параметром len? И пробел в конце ещё шумит.
@Ganzal, да. Я изначально делал функцию с итоговой длиной меньше $len, но потом понял, что на практике игра не стоит свеч.
@Maputo, Ну ровно так же как ты в каждой итерации проверяешь текущую длину результирующей строки - ты можешь проверять сумму /длины строки, единицы, и длины текущего фрагмента в буфере/ на выход за пределы допустимой длины. И прерывать цикл если добавление будет лишним. Ну это так. Вариация алгоритма. А пробел таки лишний.
@salesBT, вот вариант: PHP: function my_cut($string, $length) { $strlen = mb_strlen($string); if($strlen <= $length) { return $string; } $string2 = mb_substr($string, 0, $length, 'UTF-8'); // обрезаем и работаем со всеми кодировками и указываем исходную кодировку $position = mb_strrpos($string2, ' ', 'UTF-8'); // определение позиции последнего пробела в урезанной строке. Именно по нему и разделяем слова if($position === false) { // если нет пробелов $position = mb_strpos($string, ' ', 0, 'UTF-8'); // ищем позицию первого в исходной строке } $string = mb_substr($string, 0, $position, 'UTF-8'); // Обрезаем переменную по позиции return $string; } $text = 'Северная война закончилась в 1721 году'; echo my_cut($text, 5); // выведет 'Северная' echo '<br>'; echo my_cut($text, 17); // выведет 'Северная война' echo '<br>'; echo my_cut($text, 50); // выведет всю фразу
Была такая версия (менее требуемой длины и без лишнего пробела): PHP: function short_text($text, $len = 200) { $tarr = explode(' ', $text); $txt = ''; $i = 0; while (mb_strlen($txt) < $len && isset($tarr[$i])) { $txt .= $tarr[$i] . ' '; $i++; } return implode(' ', array_slice($tarr, 0, $i - 1)); } Вобщем давно это было - надо еще проверить функцию...
@Maputo зачем тратить время на конкатенацию строки, если можно инкрементить некий счетчик на длину текущего фрагмента буфера плюс пробельную единицу?
@Ganzal, да. Так будет быстрее работать. Согласен. PHP: function short_text($text, $len = 200) { $tarr = explode(' ', $text); $txt = 0; $i = 0; while ($txt < $len && isset($tarr[$i])) { $txt += mb_strlen($tarr[$i]) + 1; $i++; } return implode(' ', array_slice($tarr, 0, $i - 1)); }
@salesBT, ещё есть mb_strimwidth, которая обрежет строку до заданного размера и добавит вместо откинутого хвоста указанные в параметрах символы. Не по пробелам (целым словам), конечно, но тоже хороша
Большое спасибо всем! Добавил многоточие в конце при обрезке текста: PHP: return $string . ' . . .'; В итоге получилось то, что нужно: PHP: function my_cut($string, $length) { $strlen = mb_strlen($string, 'UTF-8'); if($strlen <= $length) { return $string; } $string2 = mb_substr($string, 0, $length, 'UTF-8'); // обрезаем и работаем со всеми кодировками и указываем исходную кодировку $position = mb_strrpos($string2, ' ', 'UTF-8'); // определение позиции последнего пробела в урезанной строке. Именно по нему и разделяем слова if($position === false) { // если нет пробелов $position = mb_strpos($string, ' ', 0, 'UTF-8'); // ищем позицию первого в исходной строке } $string = mb_substr($string, 0, $position, 'UTF-8'); // Обрезаем переменную по позиции return $string . ' . . .'; } $text = 'Северная война закончилась в 1721 году'; echo my_cut($text, 17);
@salesBT, вот другой вариант: PHP: function my_cut2($str, $len) { if($len >= mb_strlen($str)) { return $str; } $arr = []; $pattern = '/^.{1,'.$len.'}(?=\s|$)|^.+?(?=\s|$)/u'; preg_match($pattern, $str, $arr); return (empty($arr[0]) ? '' : $arr[0]).'…'; } $text = 'Северная война закончилась в 1721 году'; echo my_cut2($text, 5).'<br>'; echo my_cut2($text, 17).'<br>'; echo my_cut2($text, 27).'<br>'; echo my_cut2($text, 30).'<br>'; echo my_cut2($text, 37).'<br>'; echo my_cut2($text, 50).'<br>'; --- Добавлено --- Кстати, как поступать с фразой из единственного слова? --- Добавлено --- если хотим, допустим, получить три буквы из фразы "Северная"?
Я использую функцию примерно вида такого: PHP: public static function cut_utf($str, $length) { $strlength = mb_strlen($str, "utf8"); $str = ($strlength > $length) ? mb_substr($str, 0, $length, "UTF-8")."..." : $str; return $str; }