代码之家  ›  专栏  ›  技术社区  ›  JoshFinnie

从字符串中获取前100个字符,注意完整单词

  •  63
  • JoshFinnie  · 技术社区  · 15 年前

    我以前在这里也问过类似的问题,但是我需要知道这个小的调整是否可行。我想把一个字符串缩短到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 回复  |  直到 6 年前
        1
  •  120
  •   Laurel Enrique    8 年前

    你所需要做的就是使用:

    $pos=strpos($content, ' ', 200);
    substr($content,0,$pos ); 
    
        2
  •  35
  •   TJ L    15 年前

    是的,有。这是我几年前从不同论坛的一个用户那里借的一个功能,所以我不能因此而得到赞扬。

    //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 打电话。

        3
  •  20
  •   Tomalak    15 年前

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

        4
  •  13
  •   PatrikAkerstrand    15 年前

    当然。最简单的方法可能是围绕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];
    }
    

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

        5
  •  10
  •   filip    13 年前

    此函数通过添加 "..." 尽可能在单词边界处。返回的字符串的最大长度为 $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..."
        6
  •  8
  •   OMA    8 年前

    这是我的方法,基于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;
    }
    
        7
  •  4
  •   ahmed    15 年前

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

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

    祝你好运

        8
  •  4
  •   Arek - Krakiewicz.pl    12 年前

    下面是一个很好的解决方案,结尾是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 ) ? '...' : ''); 
    }
    

    输入: 洛雷姆·伊普索姆·多尔坐在阿米特的座位上,他是一位非常优秀的运动员,他是一位非常出色的速度运动员,他在拉伯和多洛尔·马格纳·阿利夸尔的比赛中发挥了重要作用。如果是最小的鹿肉,那么诺斯特鲁德的实验室就不需要支付任何费用。在巴黎的富家大教堂里,有一只可爱的海豚。除了西方国家以外,丘比特人没有胆怯,他们在工作中表现得很好。

    输出: 洛雷姆·伊普索姆·多尔坐在阿米特的座位上,他是一位非常优秀的运动员,他是一位非常出色的速度运动员,他在拉伯和多洛尔·马格纳·阿利夸尔的比赛中发挥了重要作用。他是一个很小的维尼姆人,他是一个很好的工作人员。

        9
  •  3
  •   supersan    9 年前

    接受答案的问题是结果字符串超过了限制,即它可以超过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);
    

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

    附笔。 如果计划在数据库中使用固定的WITH列(如varchar(50)等)存储截断的字符串,那么这一点尤其有用。

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

        10
  •  2
  •   katfish    11 年前

    这是为我做的…

    //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)
    
        11
  •  2
  •   Kevin K    11 年前

    我的解决方案是:

    /**
     * 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);
    
        12
  •  2
  •   Aigars Matulis    9 年前
    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)“第一个”

    print truncate('FirstStepToEternalLife', 5);
    

    字符串(5)“第一个”

        13
  •  1
  •   beaudierman    10 年前

    我为重新回答这个问题道歉,但我偶然发现了这条线索,发现了一个小问题。对于任何人想要一个字符限制,将删除超过您的给定限制的单词,上述答案工作得很好。在我的具体案例中,如果限制在所说单词的中间,我喜欢显示一个单词。我决定分享我的解决方案,以防其他人正在寻找这个功能,需要包括文字而不是删掉它们。

    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
  •   Alex    9 年前

    这是另一种方法。

    $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个字符,然后从末尾搜索到最近的单词分隔符。

        15
  •  1
  •   zarpio raj240    6 年前

    另一个更简单的方法。

    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));
    }
    
        16
  •  0
  •   Community CDub    7 年前

    wordwarp根据限制格式化字符串,并用\n 所以我们有小于50的线,ORD没有分开 根据\n 所以我们有对应于行的数组 列表收集第一个元素。

    list($short)=explode(“\n”,自动换行($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) ""
    
        17
  •  0
  •   ryanm    8 年前

    又一个答案!我对其他答案并不完全满意,我想要一个“硬截止”(如果可能的话,保证在$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;
    }
    
        18
  •  0
  •   sooraj subramanyan    8 年前

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

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