【问题标题】:php trim a stringphp修剪一个字符串
【发布时间】:2012-01-25 02:29:14
【问题描述】:

我正在尝试构建一个函数来修剪字符串,根据我的规范,它太长了。

这是我所拥有的:

function trim_me($s,$max) 
{
    if (strlen($s) > $max) 
    {
        $s = substr($s, 0, $max - 3) . '...';
    }
    return $s;
}

如果字符串比$max 长,上面将修剪一个字符串,并添加一个延续...

我想扩展该功能以处理多个单词。目前它做了它的工作,但如果我有一个字符串说:How are you today?,它有 18 个字符长。如果我运行trim_me($s,10),它将显示为How are yo...,这在美学上并不令人愉悦。我怎样才能使它在整个单词之后添加一个...。假设我运行trim_me($s,10) 我希望它显示How are you... 在单词之后添加延续。有什么想法吗?

我几乎不想在单词中间添加续行符。但是如果字符串只有一个单词,那么接续只能打破单词 then。

【问题讨论】:

  • 所以trim_me('a bbbbbbbbbbbbbbbbbbbbbbbb c', 10) 会是'a bbbbbbbbbbbbbbbbbbbbbbbb...'
  • 我收到 string(10) "How are..." 的 trim_me($s,10)
  • @ruakh 不,最多 10 个,所以可以更少。它会找到我认为的最后一个空间并使用它?
  • 您希望 $max 成为包括“...”的最大值吗?这就是您的代码所做的,但您的示例没有。

标签: php string


【解决方案1】:

所以,这就是你想要的:

<?php
// Original PHP code by Chirp Internet: www.chirp.com.au 
// Please acknowledge use of this code by including this header.
function myTruncate($string, $limit, $break=".", $pad="...") { 
    // is $break present between $limit and the end of the string? 
    if(false !== ($breakpoint = strpos($string, $break, $limit))) { 
        if($breakpoint < strlen($string) - 1) { 
            $string = substr($string, 0, $breakpoint) . $pad; 
        } 
    } 
    return $string;
}
?>

另外,您可以在http://www.the-art-of-web.com/php/truncate/阅读更多内容

【讨论】:

    【解决方案2】:
    function trim_me($s,$max) {
        if( strlen($s) <= $max) return $s;
        return substr($s,0,strrpos($s," ",$max-3))."...";
    }
    

    strrpos 是具有魔力的函数。

    【讨论】:

    • 该函数被称为trim_me,你有一个未定义的$c,我认为在没有括号的if 后面的行末尾有一个return 是不好的做法。通常使用 if 和 else 是首选,因为它使您的逻辑明确并允许扩展。
    • 我能怪我的键盘吗?还是我的疲倦? :p
    【解决方案3】:

    我已将函数命名为 str_trunc。您可以将 strict 指定为 TRUE,在这种情况下,它将只允许一个最大大小的字符串,而不再允许,否则它将搜索适合它即将完成的单词的最短字符串。

    var_dump(str_trunc('How are you today?', 10)); // string(10) "How are..."
    var_dump(str_trunc('How are you today? ', 10, FALSE)); // string(14) "How are you..."
    
    // Returns a trunctated version of $str up to $max chars, excluding $trunc.
    // $strict = FALSE will allow longer strings to fit the last word.
    function str_trunc($str, $max, $strict = TRUE, $trunc = '...') {
        if ( strlen($str) <= $max ) {
            return $str;
        } else {
            if ($strict) {
                return substr( $str, 0, strrposlimit($str, ' ', 0, $max + 1) ) . $trunc;
            } else {
                return substr( $str, 0, strpos($str, ' ', $max) ) . $trunc;
            }
        }
    }
    
    // Works like strrpos, but allows a limit
    function strrposlimit($haystack, $needle, $offset = 0, $limit = NULL) {
        if ($limit === NULL) {
            return strrpos($haystack, $needle, $offset);
        } else {
            $search = substr($haystack, $offset, $limit);
            return strrpos($search, $needle, 0);
        }
    }
    

    【讨论】:

      【解决方案4】:

      它实际上有点简单,我添加这个答案是因为the suggested duplicate 不符合您的需求(但它确实给出了一些指示)。

      你想要的是切割一个最大长度的字符串,但保留最后一个单词。所以你需要找出剪断字符串的位置(以及是否真的需要剪断它)。

      由于获取长度(strlen)和切割字符串(substr)不是您的问题(您已经使用它),要解决的问题是如何获取最后一个单词的位置范围内。

      这涉及分析字符串并找出每个单词的偏移量。字符串处理可以用正则表达式来完成。在写这篇文章时,它让我想起了一些实际上已经解决的更相似的问题:

      它正是这样做的:使用正则表达式获取“完整单词”字符串。唯一的区别是,它删除了最后一个单词(而不是扩展它)。由于您想扩展最后一个单词,因此需要使用不同的正则表达式模式。

      在正则表达式中\b 匹配单词边界。那是在一个词之前或之后。您现在要选择至少 $length 字符直到下一个单词边界。

      由于这可能在下一个单词之前包含空格,因此您可能需要修剪结果以删除末尾的这些空格。

      您可以使用正则表达式模式 (preg_replace) 和 trim 来扩展您的函数,如下所示:

      /**
       * Cut a string at length while preserving the last word.
       * 
       * @param string $str
       * @param int $length
       * @param string $suffix (optional)
       */
      function trim_word($str, $length, $suffix = '...') 
      {
          $len = strlen($str);
      
          if ($len < $length) return $str;
      
          $pattern = sprintf('/^(.{%d,}?)\b.*$/', $length);
          $str = preg_replace($pattern, '$1', $str);
          $str = trim($str);
          $str .= $suffix;
      
          return $str;
      }
      

      用法:

      $str = 'How are you today?';
      echo trim_word($str, 10); # How are you...
      

      您可以通过将模式中的最小长度减少后缀的长度来进一步扩展此功能(正如您的问题中以某种方式建议的那样,但是您在问题中给出的结果与您的代码不匹配)。

      我希望这会有所帮助。也请使用本网站的搜索功能,它并不完美,但许多宝石隐藏在现有问题中以寻找替代方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-04
        • 1970-01-01
        相关资源
        最近更新 更多