【问题标题】:Making sure PHP substr finishes on a word not a character确保 PHP substr 以单词而不是字符结束
【发布时间】:2010-11-17 00:36:27
【问题描述】:

我知道如何使用 substr 函数,但这会很高兴在一个单词的中途结束一个字符串。我希望字符串在一个单词的末尾结束,我该怎么做呢?它会涉及正则表达式吗?非常感谢任何帮助。

这是我目前所拥有的。只是 SubStr...

echo substr("$body",0,260);

干杯

【问题讨论】:

标签: php substring


【解决方案1】:

这可以用正则表达式来完成,这样的事情从字符串的开头到单词边界最多可以有 260 个字符:

$line=$body;
if (preg_match('/^.{1,260}\b/s', $body, $match))
{
    $line=$match[0];
}

或者,您可以使用 wordwrap 函数将您的 $body 分成几行,然后提取第一行。

【讨论】:

  • 我认为他们可能投了反对票,因为它不使用 PHP 谁知道。非常感谢。
  • UTF8 呢?我对正则表达式很不满意。
  • 尝试使用 /u 修饰符来匹配 UTF-8,例如/^.{1,260}\b/su
  • 好吧,即使它少于 260 个字符,它仍然会在单词边界处中断,因此会产生有效结果。但是您可以在尝试正则表达式之前检查字符串长度。
  • 这似乎运作良好。需要注意的一个极端情况是,如果前 260 个字符中根本没有空白字符,它只会返回整个字符串。如果这是一个问题,您可以添加类似 $line = mb_substr($line, 0, 260); 的内容以强制在该长度处中断。
【解决方案2】:

你可以试试这个:

   $s = substr($string, 0, 261);
   $result = substr($s, 0, strrpos($s, ' '));

【讨论】:

  • 这是最好的答案!与@achshar 解决方案相反,此解决方案允许在不超过字数限制的情况下保留整个单词。关键是使用strrpos 函数在前261 个字符中查找最后一个空格,返回该位置,然后使用substr 在该位置对字符串进行切片。请记住将所有内容包含在 if 语句中,以仅在文本大于 260 个字符时应用函数。
  • 这个解决方案可以更完美(我猜),不是对substr()+1,而是检查最后一个字符是否是空格。所以这是我对第二行的建议:$result = substr($s, -1) === " " ? trim($s) : substr($s, 0, strrpos($s, ' '));
【解决方案3】:

您可以这样做:从第 260 个字符开始找到第一个空格并将其用作裁剪标记:

$pos = strpos($body, ' ', 260);
if ($pos !== false) {
    echo substr($body, 0, $pos);
}

【讨论】:

    【解决方案4】:
    $pos = strpos($body, $wordfind);
    echo substr($body,0, (($pos)?$pos:260));
    

    【讨论】:

      【解决方案5】:
      substr($body, 0, strpos($body, ' ', 260))
      

      【讨论】:

      • 时尚的解决方案,但是 UTF-8 呢?
      • 是的,但是 strpos 不会混淆,因为现在 260 实际上是 130 个字符?
      • 如果文本短于 260 个字符,使用它可以生成 strpos 警告。
      • 这有很多问题。如前所述,如果字符串小于 260 个字符长度,或者不包含任何空格,则会失败。它也不将字符串限制为 260 个字符,而是在 260 个字符之后的空格处断开字符串,这通常不是您想要的。如果分词符是不同类型的空格(例如制表符或换行符),它也不起作用。它也不是多字节兼容的。 Paul Dixon 的 preg_match() 解决方案是一个更好的解决方案。
      • @zed 的回答纠正了本解决方案超过字符数限制的问题。
      【解决方案6】:

      我使用这个解决方案:

      $maxlength = 50;
      substr($name, 0, ($spos = strpos($name, ' ', $lcount = count($name) > $maxlength ? $lcount : $maxlength)) ? $spos : $lcount );
      

      或内联:

      substr($name, 0, ($spos = strpos($name, ' ', $lcount = count($name) > 50 ? $lcount : 50)) ? $spos : $lcount );
      

      【讨论】:

        【解决方案7】:
        function substr_word($body,$maxlength){
            if (strlen($body)<$maxlength) return $body;
            $body = substr($body, 0, $maxlength);
            $rpos = strrpos($body,' ');
            if ($rpos>0) $body = substr($body, 0, $rpos);
            return $body;
        }
        

        【讨论】:

          【解决方案8】:
          public function Strip_text($data, $size, $lastString = ""){
              $data = strip_tags($data);          
              if(mb_strlen($data, 'utf-8') > $size){
                  $result = mb_substr($data,0,mb_strpos($data,' ',$size,'utf-8'),'utf-8');
                      if(mb_strlen($result, 'utf-8') <= 0){
                      $result = mb_substr($data,0,$size,'utf-8');
                      $result = mb_substr($result, 0, mb_strrpos($result, ' ','utf-8'),'utf-8');;         
                  }
                  if(strlen($lastString) > 0) {
                      $result .= $lastString;
                  }
              }else{
              $result = $data;
              }
              return $result; 
          }
          

          将字符串传入函数Strip_text("带html标签或不带html标签的长文本", 15) 然后此函数将返回 html 字符串中不带 html 标记的前 15 个字符。当字符串小于 15 个字符时返回完整的字符串,否则返回 15 个字符的 $lastString 参数字符串。

          示例:

          Strip_text("<p>vijayDhanasekaran</p>", 5)
          

          结果:vijay

          Strip_text("<h1>vijayDhanasekaran<h1>",5,"***....")
          

          结果:vijay***....

          【讨论】:

          • 更多上下文或解释可能会很有用:它是如何工作的,为什么要使用这种方法,等等。
          • 输入utf-8字体ex“泰米尔语”时,可以得到不含无关字符的子串。
          【解决方案9】:

          试试这个功能..

          <?php
          /**
           * trims text to a space then adds ellipses if desired
           * @param string $input text to trim
           * @param int $length in characters to trim to
           * @param bool $ellipses if ellipses (...) are to be added
           * @param bool $strip_html if html tags are to be stripped
           * @param bool $strip_style if css style are to be stripped
           * @return string
           */
          function trim_text($input, $length, $ellipses = true, $strip_tag = true,$strip_style = true) {
              //strip tags, if desired
              if ($strip_tag) {
                  $input = strip_tags($input);
              }
          
              //strip tags, if desired
              if ($strip_style) {
                  $input = preg_replace('/(<[^>]+) style=".*?"/i', '$1',$input);
              }
          
              if($length=='full')
              {
          
                  $trimmed_text=$input;
          
              }
              else
              {
                  //no need to trim, already shorter than trim length
                  if (strlen($input) <= $length) {
                  return $input;
                  }
          
                  //find last space within length
                  $last_space = strrpos(substr($input, 0, $length), ' ');
                  $trimmed_text = substr($input, 0, $last_space);
          
                  //add ellipses (...)
                  if ($ellipses) {
                  $trimmed_text .= '...';
                  }       
              }
          
              return $trimmed_text;
          }
          ?>
          

          【讨论】:

            【解决方案10】:

            wordwrap 和 explode 然后第一个数组元素是你想要的 $wr=wordwrap($text,20,':'); $strs=explode(":",$wr); $strs[0]

            【讨论】:

            • 我认为这是最干净的解决方案,即使是一个班轮 - echo explode('||',wordwrap($text,20,'||'))[0]
            【解决方案11】:

            这个怎么样?

            /**
             * @param string $text
             * @param int $limit
             * @return string
             */
            public function extractUncutPhrase($text, $limit)
            {
                $delimiters = [',',' '];
                $marks = ['!','?','.'];
            
                $phrase = substr($text, 0, $limit);
                $nextSymbol = substr($text, $limit, 1);
            
            
                // Equal to original
                if ($phrase == $text) {
                    return $phrase;
                }
                // If ends with delimiter
                if (in_array($nextSymbol, $delimiters)) {
                    return $phrase;
                }
                // If ends with mark
                if (in_array($nextSymbol, $marks)) {
                    return $phrase.$nextSymbol;
                }
            
                $parts = explode(' ', $phrase);
                array_pop($parts);
            
                return implode(' ', $parts); // Additioanally you may add ' ...' here.
            }
            

            测试:

            public function testExtractUncutPhrase()
            {
                $stringUtils = new StringUtils();
            
                $text = 'infant ton-gue could make of both names nothing';
                $phrase = 'infant';
            
                $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 11));
                $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 12));
            
                $text = 'infant tongue5';
                $phrase = 'infant';
            
                $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));
                $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 11));
                $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 7));
            }
            
            public function testExtractUncutPhraseEndsWithDelimiter()
            {
                $stringUtils = new StringUtils();
            
                $text = 'infant tongue ';
                $phrase = 'infant tongue';
            
                $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));
            
                $text = 'infant tongue,';
                $phrase = 'infant tongue';
            
                $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));
            }
            
            public function testExtractUncutPhraseIsSentence()
            {
                $stringUtils = new StringUtils();
            
                $text = 'infant tongue!';
                $phrase = 'infant tongue!';
            
                $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 14));
                $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 100));
            
                $text = 'infant tongue!';
                $phrase = 'infant tongue!';
            
                $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));
            
                $text = 'infant tongue.';
                $phrase = 'infant tongue.';
            
                $this->assertEquals($phrase, $stringUtils->extractUncutPhrase($text, 13));
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2010-12-12
              • 2014-09-26
              • 2014-11-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-02-13
              相关资源
              最近更新 更多