Как обрезать строку по словам на PHP

  • 12 841
  • Комментарии: 8
Газонокосилка

Часто встречается необходимость обрезать строку, но не просто сделать это с помощью функции substr(), а так, чтобы сохранить слова целыми. Перед вами функция на PHP, которая позволяет разбивать строку по словам.

/**
 * Обрезает строку до определённого количества символов не разбивая слова.
 * @param string $str строка
 * @param int $length длина, до скольки символов обрезать
 * @param string $postfix постфикс, который добавляется к строке
 * @return string обрезанная строка
 */
function cutStr($str, $length=50, $postfix='...')
{
    if ( strlen($str) <= $length)
        return $str;

    $temp = substr($str, 0, $length);
    return substr($temp, 0, strrpos($temp, ' ') ) . $postfix;
}

А вот версия для работы с многобайтовыми кодировками:

/**
 * Обрезает строку до определённого количества символов не разбивая слова.
 * Поддерживает многобайтовые кодировки.
 * @param string $str строка
 * @param int $length длина, до скольки символов обрезать
 * @param string $postfix постфикс, который добавляется к строке
 * @param string $encoding кодировка, по-умолчанию 'UTF-8'
 * @return string обрезанная строка
 */
function mbCutString($str, $length, $postfix='...', $encoding='UTF-8')
{
    if (mb_strlen($str, $encoding) <= $length) {
        return $str;
    }

    $tmp = mb_substr($str, 0, $length, $encoding);
    return mb_substr($tmp, 0, mb_strripos($tmp, ' ', 0, $encoding), $encoding) . $postfix;
}
Понравилась статья? Оцени её!
8 комментариев
  • Кирилл Версетти пишет:

    У тебя будут проблемы с юникод строками — utf-8 это уже стандарт.

    Для проверки можешь задать строку «Привет мир!». Визуально кажется, что символов 11, но фактически ее длина 22. Поэтому если написать cutStr(‘Привет мир!’, 11), то получится неожиданный результат =)

    Тут надо работать с функциями из расширения mbstring
    http://php.net/manual/ru/ref.mbstring.php

    • Борис Заболотских пишет:

      Точно! Я эту функцию писал давно, про mb_* знаю и активно использую)
      Сейчас поправлю, благодарю за указание на ошибку!

    • Кирилл Версетти пишет:

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

      function cutString($str, $length, $postfix='...', $encoding=null) {
          $encoding = $encoding ?: mb_detect_encoding($str);
      
          if (mb_strlen($str, $encoding) <= $length) {
              return $str;
          }
      
          $tmp = mb_substr($str, 0, $length, $encoding);
          return mb_substr($tmp, 0, mb_strripos($tmp, ' ', 0, $encoding), $encoding) . $postfix;
      }
      
      $hw = 'Hello world!';
      $hwRus = 'Привет мир!';
      
      var_dump(cutString($hw, 7));
      var_dump(cutString($hwRus, 8));
      
      • Борис Заболотских пишет:

        Комментарии написали почти одновременно =)
        Мне кажется в твоём варианте mb_detect_encoding() лишнее, проще указать ‘UTF-8’ в аргументе $encoding по-умолчанию.

        • Кирилл Версетти пишет:

          А если у нас не utf-8? Либо мы изначально не знаем точно какая кодировка придет?

          На самом деле я до конца не уверен в том, что функция mb_detect_encoding() корректно работает, хоть она и встроенная. Слишком много материала в гугле на тему «как определить кодировку строки» и там народ порой такие алгоритмы пишет, что глаза на лоб лезут от непонимания =)

          Ну и потестируй еще мою, я до конца в ней не уверен =)

          • Борис Заболотских пишет:

            «На самом деле я до конца не уверен в том, что функция mb_detect_encoding() корректно работает, хоть она и встроенная.» — вот и я тоже не уверен. Лучше определить кодировку отдельно и передать её аргументом, а большинство случаев покрывает UTF-8 😉

  • Макс пишет:

    Спасибо, мужик, все работает)

  • Virbus пишет:

    Коллеги
    В задании было написано ЧТОБЫ СОХРАНЯЛИСЬ ЦЕЛЫМИ СЛОВА

    поэтому дополняю скрипт

    function cutString($str, $length, $postfix=’…’, $encoding=null) {
    $encoding = $encoding ?: mb_detect_encoding($str);

    if (mb_strlen($str, $encoding) <= $length) {
    return $str;
    }

    while (mb_substr($str, $length, (1)) != ' ') {
    // ДЛЯ ОТЛАДКИ РАСКОМЕНТИРУЙТЕ ЭТО echo $length++." ". mb_substr($str, 0, $length)."»;
    // А ТО ЧТО НИЖЕ $length++ ЗАКОММЕНТИРУЙТЕ
    $length++
    if (mb_strlen($str, $encoding) <= $length) { return $str; }
    }

    $tmp = mb_substr($str, 0, $length, $encoding);
    return mb_substr($tmp, 0, mb_strripos($tmp, ' ', 0, $encoding), $encoding) . $postfix;
    }

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *