Усечь многобайтовую строку до n символов
Вопрос
Я пытаюсь заставить этот метод работать в строковом фильтре:
public function truncate($string, $chars = 50, $terminator = ' …');
я бы этого ожидал
$in = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYXZ1234567890";
$out = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV …";
а также это
$in = "âãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝ";
$out = "âãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđ …";
То есть $chars
минус символы $terminator
нить.
Кроме того, фильтр должен обрезать границу первого слова ниже $chars
предел, например
$in = "Answer to the Ultimate Question of Life, the Universe, and Everything.";
$out = "Answer to the Ultimate Question of Life, the …";
Я почти уверен, что это должно сработать с этими шагами
- вычесть количество символов в терминаторе из максимального количества символов
- проверить, что строка длиннее рассчитанного предела, или вернуть ее без изменений
- найдите последний пробел в строке ниже расчетного предела, чтобы получить границу слова
- обрезать строку по последнему пробелу или вычисленному пределу, если последний пробел не найден
- добавить терминатор к строке
- возвращаемая строка
Однако я пробовал различные комбинации str*
и mb_*
работает сейчас, но все дали неправильные результаты.Это не может быть так сложно, поэтому я явно что-то упускаю.Кто-нибудь поделится рабочей реализацией этого? или укажите мне ресурс, где я наконец смогу понять, как это сделать.
Спасибо
P.S.Да, я проверил https://stackoverflow.com/search?q=truncate+string+php до :)
Решение
Попробуй это:
function truncate($string, $chars = 50, $terminator = ' …') {
$cutPos = $chars - mb_strlen($terminator);
$boundaryPos = mb_strrpos(mb_substr($string, 0, mb_strpos($string, ' ', $cutPos)), ' ');
return mb_substr($string, 0, $boundaryPos === false ? $cutPos : $boundaryPos) . $terminator;
}
Но вам необходимо убедиться, что ваша внутренняя кодировка настроена правильно.
Другие советы
Только что узнал, что PHP уже имеет многобайтовое усечение с
mb_strimwidth
— Получить усеченную строку указанной ширины
Однако оно не подчиняется границам слов.Но тем не менее удобно!
Обычно мне не нравится просто кодировать полный ответ на такой вопрос.Но я также только что проснулся и подумал, что, возможно, ваш вопрос поможет мне настроиться на программу до конца дня.
Я не пробовал это запускать, но это должно сработать или, по крайней мере, помочь вам пройти 90% пути.
function truncate( $string, $chars = 50, $terminate = ' ...' )
{
$chars -= mb_strlen($terminate);
if ( $chars <= 0 )
return $terminate;
$string = mb_substr($string, 0, $chars);
$space = mb_strrpos($string, ' ');
if ($space < mb_strlen($string) / 2)
return $string . $terminate;
else
return mb_substr($string, 0, $space) . $terminate;
}