Обрезать многобайтовую строку до n символов - PullRequest
7 голосов
/ 28 января 2010

Я пытаюсь включить этот метод в String Filter:

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 раньше:)

Ответы [ 3 ]

5 голосов
/ 12 ноября 2010

Только что узнал, что PHP уже имеет многобайтовое усечение с

  • mb_strimwidth - Получить усеченную строку с заданной шириной

Хотя это не подчиняется границам слов. Но, тем не менее, удобно!

3 голосов
/ 28 января 2010

Попробуйте это:

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;
}

Но вы должны убедиться, что ваша внутренняя кодировка установлена ​​правильно.

0 голосов
/ 28 января 2010

Я обычно не люблю просто кодировать полный ответ на такой вопрос. Но я также проснулся и подумал, что, возможно, ваш вопрос поможет мне настроиться на программу в течение всего дня.

Я не пытался запустить это, но это должно сработать или, по крайней мере, получить 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...