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

时间:2009-06-09 19:22:08

标签: php string

我之前曾在此问过类似的问题,但我需要知道这个小调整是否可行。我想将一个字符串缩短为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做到这一点?

18 个答案:

答案 0 :(得分:123)

您需要做的就是使用:

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

答案 1 :(得分:36)

是的,有。这是我几年前在不同论坛上向用户借用的功能,所以我不能相信它。

//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调用的第二个参数,它会自动添加省略号。

答案 2 :(得分:20)

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

答案 3 :(得分:13)

不确定。最简单的可能是在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];
}

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

答案 4 :(得分:10)

此函数通过尽可能在单词边界添加"..."来缩短字符串。返回的字符串的最大长度为$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..."

答案 5 :(得分:9)

这是我的方法,基于amir的答案,但它不会让任何单词使字符串长于限制,通过使用带负偏移的strrpos()。

简单但有效。我使用与Laravel的str_limit()辅助函数相同的语法,以防你想在非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;
}

答案 6 :(得分:4)

这对我来说很好,我在我的脚本中使用它

<?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;
}
?>
祝你好运

答案 7 :(得分:4)

这是一个很好的解决方案,最后用dotts用完整的单词

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 ) ? '...' : ''); 
}

输入: Lorem ipsum dolor sit amet,consectetur adipisicing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua。 Ut enim ad minim veniam,quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat。 Duis aute irure dolor in repreptderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur。 Excepteur sint occaecat cupidatat non proident,sunt in culpa qui officia deserunt mollit anim id est laborum。

输出: Lorem ipsum dolor sit amet,consectetur adipisicing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua。 Ut enim ad minim veniam,quis nostrud exercitation ullamco laboris nisi ut aliquip ...

答案 8 :(得分:3)

接受答案的问题是结果字符串超过了限制,即它可能超过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)等)将截断的字符串存储在数据库中,这将非常有用。

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

答案 9 :(得分:2)

这是我的解决方案:

/**
 * 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);

答案 10 :(得分:2)

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

string(25)&#34;永恒的第一步&#34;

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

string(9)&#34;第一个&#34;

print truncate('FirstStepToEternalLife', 5);
  

string(5)&#34; First&#34;

答案 11 :(得分:2)

这对我有用......

//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)

答案 12 :(得分:1)

这是你可以做到的另一种方式。

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

OR

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

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

答案 13 :(得分:1)

我为复活这个问题而道歉,但我偶然发现了这个问题并发现了一个小问题。对于任何想要删除超出给定限制的字符的字符限制的人来说,上述答案效果很好。在我的具体情况下,如果限制在所述单词的中间,我喜欢显示一个单词。我决定分享我的解决方案,以防其他人正在寻找这个功能,并且需要包含单词而不是修改它们。

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...

答案 14 :(得分:1)

我做的另一种更简单的方式。

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

答案 15 :(得分:0)

wordwrap根据限制格式化字符串,用\ n分隔它们  所以我们有小于50的线,ords没有被分开 根据\ n爆炸分裂字符串  所以我们有对应于行的数组 list收集第一个元素。

  

list($ short)= explode(“\ n”,wordwrap($ ali,50));

请代表Evert,因为我无法发表评论或代表。

这里是样本运行

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) ""

答案 16 :(得分:0)

又一个答案!我对其他答案并不完全满意,并想要一个“硬截止”(如果可能的话,在$ max_characters之前保证单词中断),所以这是我的贡献功能!

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

答案 17 :(得分:0)

##从字符串##

获取第一个有限字符
<?php 
  $content= $row->title;
  $result = substr($content, 0, 70);
  echo $result; 
  ?>