从字符串中取出前100个字符,并尊重完整的单词

我以前也问过类似的问题,但是我需要知道这个小小的调整是否可行。我想将一个字符串缩短到100个字符,并使用 $small = substr($big, 0, 100);来实现这一点。然而,这只需要前100个字符,并不关心它是否拆分一个单词。

有没有什么方法可以在保证不断字的前100个字符的情况下使用一个字符串呢?

例如:

$big = "This is a sentence that has more than 100 characters in it, and I want to return a string of only full words that is no more than 100 characters!"


$small = some_function($big);


echo $small;


// OUTPUT: "This is a sentence that has more than 100 characters in it, and I want to return a string of only"

有没有一种方法可以使用 PHP 实现这一点?

161587 次浏览

有的。这是几年前我从一个不同论坛的用户那里借来的一个功能,所以我不能把它归功于我自己。

//truncate a string only at a whitespace (by nogdog)
function truncate($text, $length) {
$length = abs((int)$length);
if(strlen($text) > $length) {
$text = preg_replace("/^(.{1,$length})(\s.*|$)/s", '\\1...', $text);
}
return($text);
}

注意,如果您不希望添加省略号,那么只需使用 '\\1'作为 preg_replace调用的第二个参数即可。

如果您将单词定义为“由空格分隔的字符序列”... ... 使用 strrpos()查找字符串中的最后一个空格,缩短到该位置,修剪结果。

当然,最简单的方法可能是在 preg _ match 周围编写一个包装器:

function limitString($string, $limit = 100) {
// Return early if the string is already shorter than the limit
if(strlen($string) < $limit) {return $string;}


$regex = "/(.{1,$limit})\b/";
preg_match($regex, $string, $matches);
return $matches[1];
}

编辑: 更新为不总是包含一个空格作为字符串的最后一个字符

这对我来说很有用,我在剧本里用过

<?PHP
$big = "This is a sentence that has more than 100 characters in it, and I want to return a string of only full words that is no more than 100 characters!";
$small = some_function($big);
echo $small;


function some_function($string){
$string = substr($string,0,100);
$string = substr($string,0,strrpos($string," "));
return $string;
}
?>

祝你好运

文字包装格式字符串根据限制,分隔他们与 n 所以我们有小于50的线,和弦是不分开的 根据 n 爆炸分离字符串 所以我们有对应线的数组 List 收集第一个元素。

List ($short) =  爆炸(“ n”,wordwraps ($ali,50)) ;

请代表 埃弗特,因为我不能评论或代表。

这里是样品运行

php >  $ali = "ali veli krbin yz doksan esikesiksld sjkas laksjald lksjd asldkjadlkajsdlakjlksjdlkaj aslkdj alkdjs akdljsalkdj ";
php > list($short) = explode("\n",wordwrap($ali ,50));
php > var_dump($short);
string(42) "ali veli krbin yz doksan esikesiksld sjkas"
php > $ali ='';
php > list($short) = explode("\n",wordwrap($ali ,50));
php > var_dump($short);
string(0) ""

你需要做的就是使用:

$pos=strpos($content, ' ', 200);
substr($content,0,$pos );

这个函数通过尽可能在单词边界添加 "..."来缩短字符串。返回的字符串的最大长度为 $len,包括 "..."

function truncate($str, $len) {
$tail = max(0, $len-10);
$trunk = substr($str, 0, $tail);
$trunk .= strrev(preg_replace('~^..+?[\s,:]\b|^...~', '...', strrev(substr($str, $tail, $len-$tail))));
return $trunk;
}

产出示例:

  • truncate("Thanks for contributing an answer to Stack Overflow!", 15)
    返回 "Thanks for..."
  • truncate("To learn more, see our tips on writing great answers.", 15)
    返回 "To learn more..."(逗号也被截断)
  • truncate("Pseudopseudohypoparathyroidism", 15)
    返回 "Pseudopseudo..."

这里是一个伟大的解决方案与点在结束与完整的单词

function text_cut($text, $length = 200, $dots = true) {
$text = trim(preg_replace('#[\s\n\r\t]{2,}#', ' ', $text));
$text_temp = $text;
while (substr($text, $length, 1) != " ") { $length++; if ($length > strlen($text)) { break; } }
$text = substr($text, 0, $length);
return $text . ( ( $dots == true && $text != '' && strlen($text_temp) > $length ) ? '...' : '');
}

输入: 我愿意承担所有的痛苦,我愿意承担所有的痛苦,我愿意承担所有的痛苦,我愿意承担所有的痛苦,我愿意承担所有的痛苦,我愿意承担所有的痛苦,我愿意承担所有的痛苦,我愿意承担所有的痛苦。至少我们应该知道,这样做的后果是什么。(德语)(德语)(德语)(德语)(德语)(德语)(德语)。除非有罪,否则我们将承担责任。

产出: 我愿意承担所有的痛苦,我愿意承担所有的痛苦,我愿意承担所有的痛苦,我愿意承担所有的痛苦,我愿意承担所有的痛苦,我愿意承担所有的痛苦,我愿意承担所有的痛苦,我愿意承担所有的痛苦。只要有一点点动力,我们就可以开始工作。

我就是这么做的。

//trim message to 100 characters, regardless of where it cuts off
$msgTrimmed = mb_substr($var,0,100);


//find the index of the last space in the trimmed message
$lastSpace = strrpos($msgTrimmed, ' ', 0);


//now trim the message at the last space so we don't cut it off in the middle of a word
echo mb_substr($msgTrimmed,0,$lastSpace)

我的解决办法是:

/**
* get_words_until() Returns a string of delimited text parts up to a certain length
* If the "words" are too long to limit, it just slices em up to the limit with an ellipsis "..."
*
* @param $paragraph - The text you want to Parse
* @param $limit - The maximum character length, e.g. 160 chars for SMS
* @param string $delimiter - Use ' ' for words and '. ' for sentences (abbreviation bug) :)
* @param null $ellipsis - Use '...' or ' (more)' - Still respects character limit
*
* @return string
*/
function get_words_until($paragraph, $limit, $delimiter = ' ', $ellipsis = null)
{
$parts = explode($delimiter, $paragraph);


$preview = "";


if ($ellipsis) {
$limit = $limit - strlen($ellipsis);
}


foreach ($parts as $part) {
$to_add = $part . $delimiter;
if (strlen($preview . trim($to_add)) <= $limit) { // Can the part fit?
$preview .= $to_add;
continue;
}
if (!strlen($preview)) { // Is preview blank?
$preview = substr($part, 0, $limit - 3) . '...'; // Forced ellipsis
break;
}
}


return trim($preview) . $ellipsis;
}

在你的情况下,它会是(例子) :

$big = "This is a sentence that has more than 100 characters in it, and I want to return a string of only full words that is no more than 100 characters!"


$small = get_words_until($big, 100);

我很抱歉重提这个问题,但是我偶然发现了这个帖子,发现了一个小问题。对于任何想要一个字符限制,将删除超过你给定的限制的话,以上的答案工作伟大。在我的特殊情况下,如果限制落在所说的单词的中间,我喜欢显示一个单词。我决定分享我的解决方案,以防其他人正在寻找这个功能,需要包括文字,而不是修剪它们。

function str_limit($str, $len = 100, $end = '...')
{
if(strlen($str) < $len)
{
return $str;
}


$str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));


if(strlen($str) <= $len)
{
return $str;
}


$out = '';
foreach(explode(' ', trim($str)) as $val)
{
$out .= $val . ' ';


if(strlen($out) >= $len)
{
$out = trim($out);
return (strlen($out) == strlen($str)) ? $out : $out . $end;
}
}
}

例子:

  • 输入: echo str_limit('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', 100, '...');
  • 输出: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore...
  • 输入: echo str_limit('Lorem ipsum', 100, '...');
  • 输出: Lorem ipsum
  • 输入: echo str_limit('Lorem ipsum', 1, '...');
  • 输出: Lorem...

还有另一种方法可以做到这一点。

$big = "This is a sentence that has more than 100 characters in it, and I want to return a string of only full words that is no more than 100 characters!"
$big = trim( $big );
$small = $big;
if( strlen( $big ) > 100 ){
$small = mb_substr( $small, 0, 100 );
$last_position = mb_strripos( $small, ' ' );
if( $last_position > 0 ){
$small = mb_substr( $small, 0, $last_position );
}
}


echo $small;

或者

 echo ( strlen( $small ) <  strlen( $big ) ? $small.'...' : $small );

这也是多字节安全的,即使没有空格也可以工作,在这种情况下,它只返回前100个字符。 它取出前100个字符,然后从末尾搜索到最近的单词分隔符。

function truncate ($str, $length) {
if (strlen($str) > $length) {
$str = substr($str, 0, $length+1);
$pos = strrpos($str, ' ');
$str = substr($str, 0, ($pos > 0)? $pos : $length);
}
return $str;
}

例如:

print truncate('The first step to eternal life is you have to die.', 25);

字符串(25)“永恒的第一步”

print truncate('The first step to eternal life is you have to die.', 12);

字符串(9)“ The first”

print truncate('FirstStepToEternalLife', 5);

字符串(5)“第一”

接受答案的问题是结果字符串超过了限制,也就是说它可以超过100个字符,因为 strpos看起来像 之后的偏移量,所以你的长度总是超过你的限制。如果最后一个单词是长的,比如 squirreled,那么你的结果的长度将是111(给你一个想法)。

一个更好的解决方案是使用 wordwrap函数:

function truncate($str, $length = 125, $append = '...') {
if (strlen($str) > $length) {
$delim = "~\n~";
$str = substr($str, 0, strpos(wordwrap($str, $length, $delim), $delim)) . $append;
}


return $str;
}




echo truncate("The quick brown fox jumped over the lazy dog.", 5);

这样,您可以确保字符串在您的限制下被截断(并且永远不会超过限制)

P.S. 如果您计划将截断的字符串存储在数据库中,使用类似 VARCHAR (50)这样的 fix-with 列,那么这一点特别有用。

P.P.S. 注意 wordwraps 中的特殊分隔符。这是为了确保您的字符串被正确截断,即使它包含换行符(否则它将在您不希望的第一个换行符时截断)。

这是我的方法,基于 Amir 的回答,但它不允许任何单词使字符串超过限制,方法是使用带负偏移量的 strrpos ()。

简单但有效。我使用了与 Laravel 的 str _ limit () helper 函数相同的语法,以防您想在非 Laravel 项目中使用它。

function str_limit($value, $limit = 100, $end = '...')
{
$limit = $limit - mb_strlen($end); // Take into account $end string into the limit
$valuelen = mb_strlen($value);
return $limit < $valuelen ? mb_substr($value, 0, mb_strrpos($value, ' ', $limit - $valuelen)) . $end : $value;
}

又一个答案!我对其他答案并不完全满意,想要一个“硬截断”(如果可能的话,保证在 $max _ 字符之前断字) ,所以这里是我的贡献函数!

/**
* Shortens a string (if necessary), trying for a non-word character before character limit, adds an ellipsis and
* returns. Falls back to a forced cut if no non-word characters exist before.
*
* @param string $content
* @param int    $max_characters - number of characters to start looking for a space / break.
* @param bool   $add_ellipsis   - add ellipsis if content is shortened
*
* @return string
*/
public static function shorten( $content, $max_characters = 100, $add_ellipsis = TRUE ) {
if ( strlen( $content ) <= $max_characters ) {
return $content;
}


// search for non-word characters
$match_count = preg_match_all( '/\W/', $content, $matches, PREG_OFFSET_CAPTURE );


// force a hard break if can't find another good solution
$pos = $max_characters;


if ( $match_count > 0 ) {
foreach ( $matches[0] as $match ) {
// check if new position fits within
if ( $match[1] <= $max_characters ) {
$pos = $match[1];
} else {
break;
}
}
}


$suffix = ( $add_ellipsis ) ? '&hellip;' : '';


return substr( $content, 0, $pos ) . $suffix;
}

# 从字符串中获取第一个有限字符 #

<?php
$content= $row->title;
$result = substr($content, 0, 70);
echo $result;
?>

另一种更简单的方式。

function limit_words($string, $word_limit = 10)
{
$words = explode(" ", $string);
if (count($words) > $word_limit) {
return implode(" ", array_splice($words, 0, $word_limit)) . ' ...';
}
return implode(" ", array_splice($words, 0, $word_limit));
}