Как обрезать строку в PHP до слова, ближайшего к определенному количеству символов?

У меня есть фрагмент кода, написанный на PHP, который извлекает блок текста из базы данных и отправляет его виджету на веб-странице. Оригинальный блок текста может быть длинной статьей или коротким предложением или двумя; но для этого виджета я не могу отобразить больше, скажем, 200 символов. Я мог бы использовать substr(), чтобы отрубить текст на 200 символов, но в результате слова были бы обрезаны в середине слова - что мне действительно нужно, так это нарезать текст в конце последнего слова до 200 символов.

32 ответа

Решение

Используя функцию переноса слов. Он разбивает текст на несколько строк так, чтобы максимальная ширина была той, которую вы указали, ломаясь за границы слов. После разделения вы просто берете первую строку:

substr($string, 0, strpos(wordwrap($string, $your_desired_width), "\n"));

Одна вещь, которую этот пользователь не обрабатывает, - это случай, когда сам текст короче желаемой ширины. Чтобы обработать этот крайний случай, нужно сделать что-то вроде:

if (strlen($string) > $your_desired_width) 
{
    $string = wordwrap($string, $your_desired_width);
    $string = substr($string, 0, strpos($string, "\n"));
}

Приведенное выше решение имеет проблему преждевременной обрезки текста, если он содержит новую строку перед фактической точкой обрезки. Вот версия, которая решает эту проблему:

function tokenTruncate($string, $your_desired_width) {
  $parts = preg_split('/([\s\n\r]+)/', $string, null, PREG_SPLIT_DELIM_CAPTURE);
  $parts_count = count($parts);

  $length = 0;
  $last_part = 0;
  for (; $last_part < $parts_count; ++$last_part) {
    $length += strlen($parts[$last_part]);
    if ($length > $your_desired_width) { break; }
  }

  return implode(array_slice($parts, 0, $last_part));
}

Кроме того, вот тестовый класс PHPUnit, используемый для тестирования реализации:

class TokenTruncateTest extends PHPUnit_Framework_TestCase {
  public function testBasic() {
    $this->assertEquals("1 3 5 7 9 ",
      tokenTruncate("1 3 5 7 9 11 14", 10));
  }

  public function testEmptyString() {
    $this->assertEquals("",
      tokenTruncate("", 10));
  }

  public function testShortString() {
    $this->assertEquals("1 3",
      tokenTruncate("1 3", 10));
  }

  public function testStringTooLong() {
    $this->assertEquals("",
      tokenTruncate("toooooooooooolooooong", 10));
  }

  public function testContainingNewline() {
    $this->assertEquals("1 3\n5 7 9 ",
      tokenTruncate("1 3\n5 7 9 11 14", 10));
  }
}

РЕДАКТИРОВАТЬ:

Специальные символы UTF8, такие как "а", не обрабатываются. Добавьте 'u' в конце REGEX, чтобы обработать это:

$parts = preg_split('/([\s\n\r]+)/u', $string, null, PREG_SPLIT_DELIM_CAPTURE);

Это вернет первые 200 символов слов:

preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, 201));
$WidgetText = substr($string, 0, strrpos(substr($string, 0, 200), ' '));

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

Я пробовал другие примеры выше, и они не дали желаемых результатов.

Следующее решение появилось, когда я заметил параметр $break функции wordwrap:

строка wordwrap (строка $str [, int $width = 75 [, строка $break = "\n" [, bool $cut = false ]]])

Вот решение:

/**
 * Truncates the given string at the specified length.
 *
 * @param string $str The input string.
 * @param int $width The number of chars at which the string will be truncated.
 * @return string
 */
function truncate($str, $width) {
    return strtok(wordwrap($str, $width, "...\n"), "\n");
}

Пример № 1.

print truncate("This is very long string with many chars.", 25);

Приведенный выше пример выведет:

This is very long string...

Пример № 2.

print truncate("This is short string.", 25);

Приведенный выше пример выведет:

This is short string.

Помните, что когда вы разбиваете слово словом где угодно, некоторые языки, такие как китайский и японский, не используют пробел для разделения слов. Кроме того, злонамеренный пользователь может просто ввести текст без пробелов или использовать некоторый аналог Unicode со стандартным пробелом, и в этом случае любое используемое вами решение может в конечном итоге отобразить весь текст в любом случае. Обходным путем может быть проверка длины строки после разделения на пробелы как обычно, а затем, если строка все еще превышает ненормальный предел - в данном случае, возможно, 225 символов, - продолжая и тупо разделяя ее на этом пределе.

Еще одна оговорка с такими вещами, когда речь идет о не-ASCII символах; Строки, содержащие их, могут быть интерпретированы стандартным PHP strlen() как более длинные, чем они есть на самом деле, потому что один символ может занимать два или более байтов вместо одного. Если вы просто используете функции strlen()/substr() для разделения строк, вы можете разделить строку в середине символа! В случае сомнений mb_strlen()/ mb_substr () немного более надежны.

Используйте strpos и substr:

<?php

$longString = "I have a code snippet written in PHP that pulls a block of text.";
$truncated = substr($longString,0,strpos($longString,' ',30));

echo $truncated;

Это даст вам обрезанную строку в первом пробеле после 30 символов.

Ну вот:

function neat_trim($str, $n, $delim='…') {
   $len = strlen($str);
   if ($len > $n) {
       preg_match('/(.{' . $n . '}.*?)\b/', $str, $matches);
       return rtrim($matches[1]) . $delim;
   }
   else {
       return $str;
   }
}
$shorttext = preg_replace('/^([\s\S]{1,200})[\s]+?[\s\S]+/', '$1', $fulltext);

Описание:

  • ^ - начать с начала строки
  • ([\s\S]{1,200}) - получить от 1 до 200 любого персонажа
  • [\s]+? - не включать пробелы в конце короткого текста, чтобы мы могли избежать word ... вместо word...
  • [\s\S]+ - сопоставить весь другой контент

тесты:

  1. regex101.com давайте добавим к or несколько других r
  2. regex101.comorrrr ровно 200 символов.
  3. regex101.com после пятого rorrrrr не входит.

Наслаждаться.

Вот моя функция, основанная на подходе @Cd-MaN.

function shorten($string, $width) {
  if(strlen($string) > $width) {
    $string = wordwrap($string, $width);
    $string = substr($string, 0, strpos($string, "\n"));
  }

  return $string;
}

Удивительно, как сложно найти идеальное решение этой проблемы. Я еще не нашел ответ на этой странице, который не дает сбой, по крайней мере, в некоторых ситуациях (особенно, если строка содержит символы новой строки или табуляции, или если разрыв слова - это что-то отличное от пробела, или если строка имеет UTF-8 многобайтовых символов).

Вот простое решение, которое работает во всех случаях. Здесь были похожие ответы, но модификатор "s" важен, если вы хотите, чтобы он работал с многострочным вводом, а модификатор "u" позволяет правильно оценивать многобайтовые символы UTF-8.

function wholeWordTruncate($s, $characterCount) 
{
    if (preg_match("/^.{1,$characterCount}\b/su", $s, $match)) return $match[0];
    return $s;
}

Один возможный крайний случай с этим... если строка не имеет пробелов в первых символах $characterCount, она вернет всю строку. Если вы предпочитаете, чтобы он вызывал разрыв в $characterCount, даже если это не граница слова, вы можете использовать это:

function wholeWordTruncate($s, $characterCount) 
{
    if (preg_match("/^.{1,$characterCount}\b/su", $s, $match)) return $match[0];
    return mb_substr($return, 0, $characterCount);
}

Последний вариант, если вы хотите добавить многоточие, если оно обрезает строку...

function wholeWordTruncate($s, $characterCount, $addEllipsis = ' …') 
{
    $return = $s;
    if (preg_match("/^.{1,$characterCount}\b/su", $s, $match)) 
        $return = $match[0];
    else
        $return = mb_substr($return, 0, $characterCount);
    if (strlen($s) > strlen($return)) $return .= $addEllipsis;
    return $return;
}

Это небольшое исправление для ответа Mattmac:

preg_replace('/\s+?(\S+)?$/', '', substr($string . ' ', 0, 201));

Единственное отличие заключается в добавлении пробела в конце строки $. Это гарантирует, что последнее слово не обрезается в соответствии с комментарием ReX357.

У меня недостаточно очков репутации, чтобы добавить это в качестве комментария.

Я бы использовал для этого функцию preg_match, так как вы хотите получить довольно простое выражение.

$matches = array();
$result = preg_match("/^(.{1,199})[\s]/i", $text, $matches);

Выражение означает "соответствует любой подстроке, начиная с начала длины 1-200, которая заканчивается пробелом". Результат в $ результате, а совпадение в $ совпадений. Это заботится о вашем первоначальном вопросе, который конкретно заканчивается в любом месте. Если вы хотите, чтобы это заканчивалось на новых строках, измените регулярное выражение на:

$result = preg_match("/^(.{1,199})[\n]/i", $text, $matches);

Итак, я получил другую версию этого, основанную на ответах выше, но принимая во внимание больше вещей (utf-8, \n и;), а также строку, зачеркнутую шорткодами wordpress, закомментированными при использовании с wp.

function neatest_trim($content, $chars) 
  if (strlen($content) > $chars) 
  {
    $content = str_replace('&nbsp;', ' ', $content);
    $content = str_replace("\n", '', $content);
    // use with wordpress    
    //$content = strip_tags(strip_shortcodes(trim($content)));
    $content = strip_tags(trim($content));
    $content = preg_replace('/\s+?(\S+)?$/', '', mb_substr($content, 0, $chars));

    $content = trim($content) . '...';
    return $content;
  }
/*
Cut the string without breaking any words, UTF-8 aware 
* param string $str The text string to split
* param integer $start The start position, defaults to 0
* param integer $words The number of words to extract, defaults to 15
*/
function wordCutString($str, $start = 0, $words = 15 ) {
    $arr = preg_split("/[\s]+/",  $str, $words+1);
    $arr = array_slice($arr, $start, $words);
    return join(' ', $arr);
}

Использование:

$input = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna liqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.';
echo wordCutString($input, 0, 10); 

Это выведет первые 10 слов.

preg_split Функция используется для разделения строки на подстроки. Границы, по которым должна разбиваться строка, задаются с помощью шаблона регулярных выражений.

preg_split Функция принимает 4 параметра, но только первые 3 относятся к нам прямо сейчас.

Первый параметр - шаблон Первый параметр - это шаблон регулярных выражений, по которому нужно разбить строку. В нашем случае мы хотим разбить строку по границам слова. Поэтому мы используем предопределенный класс символов \s который соответствует пробельным символам, таким как пробел, табуляция, возврат каретки и перевод строки.

Второй параметр - строка ввода Вторым параметром является длинная текстовая строка, которую мы хотим разделить.

Третий параметр - предел Третий параметр указывает количество подстрок, которые должны быть возвращены. Если вы установите ограничение на n, preg_split вернет массив из n элементов. Первый n-1 элементы будут содержать подстроки. Последний (n th) элемент будет содержать остальную часть строки.

Вы можете использовать это:

      function word_shortener($text, $words=10, $sp='...'){

  $all = explode(' ', $text);
  $str = '';
  $count = 1;

  foreach($all as $key){
    $str .= $key . ($count >= $words ? '' : ' ');
    $count++;
    if($count > $words){
      break;
    }
  }

  return $str . (count($all) <= $words ? '' : $sp);

}

Примеры:

      word_shortener("Hello world, this is a text", 3); // Hello world, this...
word_shortener("Hello world, this is a text", 3, ''); // Hello world, this
word_shortener("Hello world, this is a text", 3, '[read more]'); // Hello world, this[read more]

У меня есть функция, которая делает почти то, что вы хотите, если вы сделаете несколько правок, она точно подойдет:

<?php
function stripByWords($string,$length,$delimiter = '<br>') {
    $words_array = explode(" ",$string);
    $strlen = 0;
    $return = '';
    foreach($words_array as $word) {
        $strlen += mb_strlen($word,'utf8');
        $return .= $word." ";
        if($strlen >= $length) {
            $strlen = 0;
            $return .= $delimiter;
        }
    }
    return $return;
}
?>

Основано на регулярном выражении @Justin Poliey:

// Trim very long text to 120 characters. Add an ellipsis if the text is trimmed.
if(strlen($very_long_text) > 120) {
  $matches = array();
  preg_match("/^(.{1,120})[\s]/i", $very_long_text, $matches);
  $trimmed_text = $matches[0]. '...';
}

Хотя это довольно старый вопрос, я решил, что предоставлю альтернативу, поскольку он не упоминался и действителен для PHP 4.3+.

Вы можете использовать sprintf семейство функций для усечения текста с помощью %.ℕs модификатор точности.

Период . за которым следует целое число, значение которого зависит от спецификатора:

  • Для спецификаторов e, E, f и F: это количество цифр, печатаемых после десятичной точки (по умолчанию это 6).
  • Для спецификаторов g и G: это максимальное количество печатаемых значащих цифр.
  • Для спецификатора s: он действует как точка отсечения, устанавливая максимальный предел символов для строки

Простое усечение https://3v4l.org/QJDJU

$string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var_dump(sprintf('%.10s', $string));

Результат

string(10) "0123456789"

Расширенное усечение https://3v4l.org/FCD21

поскольку sprintf функционирует аналогично substrи частично отрежет слова. Приведенный ниже подход гарантирует, что слова не будут обрезаны с помощьюstrpos(wordwrap(..., '[break]'), '[break]')со специальным разделителем. Это позволяет нам получить позицию и убедиться, что мы не совпадаем со стандартными структурами предложений.

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

function truncate($string, $width, $on = '[break]') {
    if (strlen($string) > $width && false !== ($p = strpos(wordwrap($string, $width, $on), $on))) {
        $string = sprintf('%.'. $p . 's', $string);
    }
    return $string;
}
var_dump(truncate('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', 20));

var_dump(truncate("Lorem Ipsum is simply dummy text of the printing and typesetting industry.", 20));

var_dump(truncate("Lorem Ipsum\nis simply dummy text of the printing and typesetting industry.", 20));

Результат

/* 
string(36) "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"  
string(14) "Lorem Ipsum is" 
string(14) "Lorem Ipsum
is" 
*/

Результаты с использованием wordwrap($string, $width) или strtok(wordwrap($string, $width), "\n")

/*
string(14) "Lorem Ipsum is"
string(11) "Lorem Ipsum"
*/

Вот как я это сделал:

$string = "I appreciate your service & idea to provide the branded toys at a fair rent price. This is really a wonderful to watch the kid not just playing with variety of toys but learning faster compare to the other kids who are not using the BooksandBeyond service. We wish you all the best";

print_r(substr($string, 0, strpos(wordwrap($string, 250), "\n")));

️ Функция нескольких вариантов использования

  • Разрешить прерывание в качестве опции
  • Разрешить подсчет символов как вариант
  • Разрешить или нет указывать и добавлять символ многоточия

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

При необходимости вы можете внести свои собственные корректировки, добавив дополнительные параметры, проверки и т. д.

      /**
 * Truncate text by characters
 *
 * @param $text String - text to truncate
 * @param $chars Integer - number of characters to truncate to - default 40
 * @param $breakWord Boolean - if true, will break on word boundaries - when false, could lead to strings longer than $chars
 * @param $ellipsis String - if set, will append to truncated text, '…' character by default
 */
public static function truncateTextByChars(
    $text,
    $chars = 40,
    $breakWord = false,
    $ellipsis = '…')
{
    if (empty($text)) {
        return null;
    }

    if ($breakWord) {
        $truncate = substr($text, 0, $chars);
        return $ellipsis && strlen($truncate) < strlen($text)
            ? $truncate . $ellipsis
            : $truncate;
    }

    // This will allow strings longer than $chars
    // eg. if the LAST WORD is within the first $chars chars
    if (strlen($text) > $chars) {
        $shortened = (substr($text,0,strpos($text,' ',$chars)));
        // make sure we don't cut off mid last-word and wind up with nothing
        $final = $ellipsis && strlen($shortened) > 0
            ? $shortened . $ellipsis
            : $text;
    } else {
        $final = $text;
    }
    return $final;
}

Примеры:

      // Defaults - chars:40; breakWord:false; ellipsis:'…',
>>> HelpersTrait::truncateTextByChars('DC Office of Cable Television, Film, Music, and Entertainment');
=> "DC Office of Cable Television, Film, Music,…"

// breakWord:true; ellipsis:false
>>> HelpersTrait::truncateTextByChars('DC Office of Cable Television, Film, Music, and Entertainment', 40, true, false);
=> "DC Office of Cable Television, Film, Mus"

// breakWord:true; ellipsis:'…'
>>> HelpersTrait::truncateTextByChars('DC Office of Cable Television, Film, Music, and Entertainment', 40, true);
=> "DC Office of Cable Television, Film, Mus…"
// a looonnng string ...
$str = "Le Lorem Ipsum est simplement du 
faux texte employé dans la composition et 
la mise en page avant impression. 
Le Lorem Ipsum est le faux texte standard de 
l'imprimerie depuis les années 1500, quand un 
imprimeur anonyme assembla ensemble des morceaux 
de texte pour réaliser un livre spécimen de polices
de texte. Il n'a pas fait que survivre cinq siècles,
mais s'est aussi adapté à la bureautique informatique,
sans que son contenu n'en soit modifié. Il a été 
popularisé dans les années 1960 grâce à la vente 
de feuilles Letraset contenant des passages du
Lorem Ipsum, et, plus récemment, par son inclusion 
dans des applications de mise en page de texte, 
comme Aldus PageMaker";
// number chars to cut
$number_to_cut = 300;
// string truncated in one line !
$truncated_string = 
substr($str, 0, strrpos(substr($str, 0, $number_to_cut), ' '));
// test return
echo $truncated_string;

// variation (add ellipsis) : echo $truncated_string.' ...';

// output :
/* Le Lorem Ipsum est simplement du 
faux texte employé dans la composition et 
la mise en page avant impression. 
Le Lorem Ipsum est le faux texte standard de 
l'imprimerie depuis les années 1500, quand un 
imprimeur anonyme assembla ensemble des morceaux 
de texte pour réaliser un livre
*/
      function trunc($phrase, $max_words) {
       $phrase_array = explode(' ',$phrase);
       if(count($phrase_array) > $max_words && $max_words > 0)
          $phrase = implode(' ',array_slice($phrase_array, 0, $max_words)).'...';
       return $phrase;
    }

Я знаю, что это старо, но...

function _truncate($str, $limit) {
    if(strlen($str) < $limit)
        return $str;
    $uid = uniqid();
    return array_shift(explode($uid, wordwrap($str, $limit, $uid)));
}

Я считаю это работает:

функция abbreviate_string_to_whole_word($ строка,$max_length,$ буфер) {

if (strlen($string)>$max_length) {
    $string_cropped=substr($string,0,$max_length-$buffer);
    $last_space=strrpos($string_cropped, " ");
    if ($last_space>0) {
        $string_cropped=substr($string_cropped,0,$last_space);
    }
    $abbreviated_string=$string_cropped."&nbsp;...";
}
else {
    $abbreviated_string=$string;
}

return $abbreviated_string;

}

Буфер позволяет вам настроить длину возвращаемой строки.

Добавлены операторы IF/ELSEIF в код от Dave и AmalMurali для обработки строк без пробелов

if ((strpos($string, ' ') !== false) && (strlen($string) > 200)) { 
    $WidgetText = substr($string, 0, strrpos(substr($string, 0, 200), ' ')); 
} 
elseif (strlen($string) > 200) {
    $WidgetText = substr($string, 0, 200);
}

Насколько я видел, все решения здесь действительны только для случая, когда начальная точка зафиксирована.

Позволяя вам повернуть это:


В это:

       Lorem ipsum dolor sit amet, consectetur...

Что, если вы хотите обрезать слова, окружающие определенный набор ключевых слов?

Обрежьте текст, окружающий определенный набор ключевых слов.

Цель состоит в том, чтобы преобразовать это:

      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna liqua. Ut enim ad minim veniam.

В это:

      ...consectetur adipisicing elit, sed do eiusmod tempor...

Это очень распространенная ситуация при отображении результатов поиска, отрывков и т. Д. Для этого мы можем использовать эти два метода вместе:

          /**
     * Return the index of the $haystack matching $needle,
     * or NULL if there is no match.
     *
     * This function is case-insensitive  
     * 
     * @param string $needle
     * @param array $haystack
     * @return false|int
     */
    function regexFindInArray(string $needle, array $haystack): ?int
    {
        for ($i = 0; $i < count($haystack); $i++) {
            if (preg_match('/' . preg_quote($needle) . '/i', $haystack[$i]) === 1) {
                return $i;
            }
        }
        return null;
    }

    /**
     * If the keyword is not present, it returns the maximum number of full 
     * words that the max number of characters provided by $maxLength allow,
     * starting from the left.
     *
     * If the keyword is present, it adds words to both sides of the keyword
     * keeping a balanace between the length of the suffix and the prefix.
     *
     * @param string $text
     * @param string $keyword
     * @param int $maxLength
     * @param string $ellipsis
     * @return string
     */
    function truncateWordSurroundingsByLength(string $text, string $keyword, 
            int $maxLength, string $ellipsis): string
    {
        if (strlen($text) < $maxLength) {
            return $text;
        }

        $pattern = '/' . '^(.*?)\s' .
                   '([^\s]*' . preg_quote($keyword) . '[^\s]*)' .
                   '\s(.*)$' . '/i';
        preg_match($pattern, $text, $matches);

        // break everything into words except the matching keywords, 
        // which can contain spaces
        if (count($matches) == 4) {
            $words = preg_split("/\s+/", $matches[1], -1, PREG_SPLIT_NO_EMPTY);
            $words[] = $matches[2];
            $words = array_merge($words, 
                              preg_split("/\s+/", $matches[3], -1, PREG_SPLIT_NO_EMPTY));
        } else {
            $words = preg_split("/\s+/", $text, -1, PREG_SPLIT_NO_EMPTY);
        }

        // find the index of the matching word
        $firstMatchingWordIndex = regexFindInArray($keyword, $words) ?? 0;

        $length = false;
        $prefixLength = $suffixLength = 0;
        $prefixIndex = $firstMatchingWordIndex - 1;
        $suffixIndex = $firstMatchingWordIndex + 1;

        // Initialize the text with the matching word
        $text = $words[$firstMatchingWordIndex];

        while (($prefixIndex >= 0 or $suffixIndex <= count($words))
                and strlen($text) < $maxLength and strlen($text) !== $length) {
            $length = strlen($text);
            if (isset($words[$prefixIndex])
                and (strlen($text) + strlen($words[$prefixIndex]) <= $maxLength)
                and ($prefixLength <= $suffixLength 
                     or strlen($text) + strlen($words[$suffixIndex]) <= $maxLength)) {
                $prefixLength += strlen($words[$prefixIndex]);
                $text = $words[$prefixIndex] . ' ' . $text;
                $prefixIndex--;
            }
            if (isset($words[$suffixIndex])
                and (strlen($text) + strlen($words[$suffixIndex]) <= $maxLength)
                and ($suffixLength <= $prefixLength 
                     or strlen($text) + strlen($words[$prefixIndex]) <= $maxLength)) {
                $suffixLength += strlen($words[$suffixIndex]);
                $text = $text . ' ' . $words[$suffixIndex];
                $suffixIndex++;
            }
        }

        if ($prefixIndex > 0) {
            $text = $ellipsis . ' ' . $text;
        }
        if ($suffixIndex < count($words)) {
            $text = $text . ' ' . $ellipsis;
        }

        return $text;
    }

Теперь вы можете:

      $text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do' .
        'iusmod tempor incididunt ut labore et dolore magna liqua. Ut enim' .
        'ad minim veniam.';

$text = truncateWordSurroundingsByLength($text, 'elit', 25, '...');

var_dump($text); // string(32) "... adipisicing elit, sed do ..."

Выполните код .

Я создаю функцию, более похожую на substr, и использую идею @Dave.

function substr_full_word($str, $start, $end){
    $pos_ini = ($start == 0) ? $start : stripos(substr($str, $start, $end), ' ') + $start;
    if(strlen($str) > $end){ $pos_end = strrpos(substr($str, 0, ($end + 1)), ' '); } // IF STRING SIZE IS LESSER THAN END
    if(empty($pos_end)){ $pos_end = $end; } // FALLBACK
    return substr($str, $pos_ini, $pos_end);
}

Ps.: Полная длина реза может быть меньше, чем длина.

Я использовал это раньше

<?php
    $your_desired_width = 200;
    $string = $var->content;
    if (strlen($string) > $your_desired_width) {
        $string = wordwrap($string, $your_desired_width);
        $string = substr($string, 0, strpos($string, "\n")) . " More...";
    }
    echo $string;
?>

Использовать этот:

следующий код удалит ','. Если у вас есть какой-либо другой символ или подстрока, вы можете использовать это вместо ','

substr($string, 0, strrpos(substr($string, 0, $comparingLength), ','))

// если у вас есть другая строковая учетная запись для

substr($string, 0, strrpos(substr($string, 0, $comparingLength-strlen($currentString)), ','))

Я считаю, что это самый простой способ сделать это:

$lines = explode('♦♣♠',wordwrap($string, $length, '♦♣♠'));
$newstring = $lines[0] . ' &bull; &bull; &bull;';

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

Другие вопросы по тегам