복붙노트

PHP에서 문자열을 특정 문자 수와 가장 가까운 단어로 자르는 방법?

PHP

PHP에서 문자열을 특정 문자 수와 가장 가까운 단어로 자르는 방법?

데이터베이스에서 텍스트 블록을 가져 와서 웹 페이지의 위젯으로 보내는 코드 스 니펫이 PHP로 작성되었습니다. 원본 텍스트 블록은 긴 글이나 짧은 문장 또는 두 개일 수 있습니다. 이 위젯의 ​​경우 200자를 초과하여 표시 할 수는 없습니다. substr ()을 사용하여 200 개의 문자로 텍스트를 잘라낼 수는 있지만 결과는 단어 중간에서 생략 될 것입니다. 실제로 원하는 것은 200 개의 문자 전에 마지막 단어의 끝에 텍스트를 잘라내는 것입니다.

해결법

  1. ==============================

    1.단어 랩 기능을 사용합니다. 그것은 최대 너비가 단어 경계에서 깨지면서 지정한 단어가되도록 여러 행의 텍스트를 나눕니다. 분할 후에는 첫 번째 줄을 간단하게 가져옵니다.

    단어 랩 기능을 사용합니다. 그것은 최대 너비가 단어 경계에서 깨지면서 지정한 단어가되도록 여러 행의 텍스트를 나눕니다. 분할 후에는 첫 번째 줄을 간단하게 가져옵니다.

    substr($string, 0, strpos(wordwrap($string, $your_desired_width), "\n"));
    

    이 oniner가 처리하지 못하는 한 가지는 텍스트 자체가 원하는 너비보다 짧은 경우입니다. 이 edge-case를 처리하려면 다음과 같이해야합니다.

    if (strlen($string) > $your_desired_width) 
    {
        $string = wordwrap($string, $your_desired_width);
        $string = substr($string, 0, strpos($string, "\n"));
    }
    

    위의 솔루션은 실제 커팅 포인트 이전에 줄 바꿈이 포함 된 경우 텍스트를 조기에 자르는 문제가 있습니다. 이 문제를 해결하는 버전은 다음과 같습니다.

    function tokenTruncate($string, $your_desired_width) {
      $parts = preg_split('/([\s\n\r]+)/', $string, null, PREG_SPLIT_DELIM_CAPTURE);
      $parts_count = count($parts);
    
      $length = 0;
      $last_part = 0;
      for (; $last_part < $parts_count; ++$last_part) {
        $length += strlen($parts[$last_part]);
        if ($length > $your_desired_width) { break; }
      }
    
      return implode(array_slice($parts, 0, $last_part));
    }
    

    또한 다음은 구현을 테스트하는 데 사용되는 PHPUnit 테스트 클래스입니다.

    class TokenTruncateTest extends PHPUnit_Framework_TestCase {
      public function testBasic() {
        $this->assertEquals("1 3 5 7 9 ",
          tokenTruncate("1 3 5 7 9 11 14", 10));
      }
    
      public function testEmptyString() {
        $this->assertEquals("",
          tokenTruncate("", 10));
      }
    
      public function testShortString() {
        $this->assertEquals("1 3",
          tokenTruncate("1 3", 10));
      }
    
      public function testStringTooLong() {
        $this->assertEquals("",
          tokenTruncate("toooooooooooolooooong", 10));
      }
    
      public function testContainingNewline() {
        $this->assertEquals("1 3\n5 7 9 ",
          tokenTruncate("1 3\n5 7 9 11 14", 10));
      }
    }
    

    'à'와 같은 특수 UTF8 문자는 처리되지 않습니다. REGEX의 끝에 'u'를 추가하여 처리하십시오.

    $ parts = preg_split ( '/ ([\ s \ n \ r] +) / u', $ string, null, PREG_SPLIT_DELIM_CAPTURE);

  2. ==============================

    2.그러면 단어의 처음 200자를 반환합니다.

    그러면 단어의 처음 200자를 반환합니다.

    preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, 201));
    
  3. ==============================

    3.

    $WidgetText = substr($string, 0, strrpos(substr($string, 0, 200), ' '));
    

    그리고 거기에 당신은 그것을 가지고 있습니다 - 가장 긴 문자열 길이를 유지하면서 가장 가까운 전체 단어로 문자열을 자르는 신뢰할 수있는 방법.

    위의 다른 예제를 시도했지만 원하는 결과를 얻지 못했습니다.

  4. ==============================

    4.다음 솔루션은 wordwrap 함수의 $ break 매개 변수를 발견했을 때 생겼습니다.

    다음 솔루션은 wordwrap 함수의 $ break 매개 변수를 발견했을 때 생겼습니다.

    해결책은 다음과 같습니다.

    /**
     * Truncates the given string at the specified length.
     *
     * @param string $str The input string.
     * @param int $width The number of chars at which the string will be truncated.
     * @return string
     */
    function truncate($str, $width) {
        return strtok(wordwrap($str, $width, "...\n"), "\n");
    }
    

    예제 # 1.

    print truncate("This is very long string with many chars.", 25);
    

    위의 예는 다음과 같이 출력됩니다.

    This is very long string...
    

    예제 # 2.

    print truncate("This is short string.", 25);
    

    위의 예는 다음과 같이 출력됩니다.

    This is short string.
    
  5. ==============================

    5.중국어와 일본어와 같은 일부 언어에서 단어를 분리 할 때 공백 문자를 사용하지 않는 "단어"로 분할 할 때마다 언제든지 염두에 두십시오. 또한 악의적 인 사용자는 공백없이 텍스트를 입력하거나 표준 공백 문자와 비슷한 일부 유니 코드를 사용할 수 있습니다.이 경우 사용하는 솔루션에 따라 텍스트 전체가 표시 될 수 있습니다. 이 문제를 해결하는 방법은 정상적으로 공백에 문자열을 분할 한 후 문자열 길이를 확인한 다음 문자열이 여전히 비정상적인 한계를 넘으면 (이 경우 225 자까지) 계속 시도하고 그 한계에서 멍청하게 분할하는 것입니다.

    중국어와 일본어와 같은 일부 언어에서 단어를 분리 할 때 공백 문자를 사용하지 않는 "단어"로 분할 할 때마다 언제든지 염두에 두십시오. 또한 악의적 인 사용자는 공백없이 텍스트를 입력하거나 표준 공백 문자와 비슷한 일부 유니 코드를 사용할 수 있습니다.이 경우 사용하는 솔루션에 따라 텍스트 전체가 표시 될 수 있습니다. 이 문제를 해결하는 방법은 정상적으로 공백에 문자열을 분할 한 후 문자열 길이를 확인한 다음 문자열이 여전히 비정상적인 한계를 넘으면 (이 경우 225 자까지) 계속 시도하고 그 한계에서 멍청하게 분할하는 것입니다.

    비 ASCII 문자의 경우 이와 같은 문제가 하나 더 있습니다. 그것들을 포함하는 문자열은 PHP의 표준 strlen ()이 실제보다 길어서 해석 될 수 있습니다. 왜냐하면 한 문자가 단 하나가 아닌 두 개 이상의 바이트를 가질 수 있기 때문입니다. strlen () / substr () 함수를 사용하여 문자열을 분할하는 경우 문자 중간에 문자열을 분할 할 수 있습니다! 의심 스러울 때, mb_strlen () / mb_substr ()은 약간 더 확실합니다.

  6. ==============================

    6.strpos 및 substr을 사용하십시오.

    strpos 및 substr을 사용하십시오.

    <?php
    
    $longString = "I have a code snippet written in PHP that pulls a block of text.";
    $truncated = substr($longString,0,strpos($longString,' ',30));
    
    echo $truncated;
    

    이렇게하면 30 자 뒤에 첫 번째 공백에서 잘린 문자열을 얻을 수 있습니다.

  7. ==============================

    7.여기 @ Cd-MaN의 접근 방식에 기반한 제 기능이 있습니다.

    여기 @ Cd-MaN의 접근 방식에 기반한 제 기능이 있습니다.

    function shorten($string, $width) {
      if(strlen($string) > $width) {
        $string = wordwrap($string, $width);
        $string = substr($string, 0, strpos($string, "\n"));
      }
    
      return $string;
    }
    
  8. ==============================

    8.여기 있습니다 :

    여기 있습니다 :

    function neat_trim($str, $n, $delim='…') {
       $len = strlen($str);
       if ($len > $n) {
           preg_match('/(.{' . $n . '}.*?)\b/', $str, $matches);
           return rtrim($matches[1]) . $delim;
       }
       else {
           return $str;
       }
    }
    
  9. ==============================

    9.이 문제에 대한 완벽한 해결책을 찾는 것이 얼마나 까다 롭다는 것이 놀랍습니다. 아직 어떤 상황에서 실패하지 않는이 페이지에 대한 답을 찾지 못했습니다 (특히 줄에 줄 바꾸기 또는 탭이 포함되어 있거나 단어 나누기가 공백 이외의 문자이거나 문자열에 UTF- 8 멀티 바이트 문자).

    이 문제에 대한 완벽한 해결책을 찾는 것이 얼마나 까다 롭다는 것이 놀랍습니다. 아직 어떤 상황에서 실패하지 않는이 페이지에 대한 답을 찾지 못했습니다 (특히 줄에 줄 바꾸기 또는 탭이 포함되어 있거나 단어 나누기가 공백 이외의 문자이거나 문자열에 UTF- 8 멀티 바이트 문자).

    다음은 모든 경우에 적용되는 간단한 솔루션입니다. 여기에도 비슷한 대답이 있지만 "s"한정자는 여러 줄 입력을 사용하려면 중요하며 "u"한정자는 UTF-8 멀티 바이트 문자를 올바르게 평가합니다.

    function wholeWordTruncate($s, $characterCount) 
    {
        if (preg_match("/^.{1,$characterCount}\b/su", $s, $match)) return $match[0];
        return $s;
    }
    

    한 가지 가능한 경우는 ... 문자열이 첫 번째 $ characterCount 문자에서 공백을 전혀 가지지 않으면 전체 문자열을 반환합니다. 단어 경계가 아니더라도 $ characterCount에서 휴식을 취하기를 원한다면 다음을 사용할 수 있습니다 :

    function wholeWordTruncate($s, $characterCount) 
    {
        if (preg_match("/^.{1,$characterCount}\b/su", $s, $match)) return $match[0];
        return mb_substr($return, 0, $characterCount);
    }
    

    하나의 마지막 옵션, 문자열을 자르면 줄임표를 추가하고 싶다면 ...

    function wholeWordTruncate($s, $characterCount, $addEllipsis = ' …') 
    {
        $return = $s;
        if (preg_match("/^.{1,$characterCount}\b/su", $s, $match)) 
            $return = $match[0];
        else
            $return = mb_substr($return, 0, $characterCount);
        if (strlen($s) > strlen($return)) $return .= $addEllipsis;
        return $return;
    }
    
  10. ==============================

    10.

    $shorttext = preg_replace('/^([\s\S]{1,200})[\s]+?[\s\S]+/', '$1', $fulltext);
    

    기술:

    테스트 :

    즐겨.

  11. ==============================

    11.preg_match 함수를 사용하여 원하는대로 간단하게 표현할 수 있습니다.

    preg_match 함수를 사용하여 원하는대로 간단하게 표현할 수 있습니다.

    $matches = array();
    $result = preg_match("/^(.{1,199})[\s]/i", $text, $matches);
    

    이 표현식은 "길이가 1-200 인 공백으로 끝나는 부분부터 시작하여 모든 부분 문자열에 일치"를 의미합니다. 결과는 $ result에 있고 일치 항목은 $ matches에 있습니다. 그 질문은 원래의 질문을 처리합니다.이 질문은 특히 어떤 공간에서도 끝납니다. 개행을 끝내려면 정규식을 다음과 같이 변경하십시오.

    $result = preg_match("/^(.{1,199})[\n]/i", $text, $matches);
    
  12. ==============================

    12.좋아, 그래서 위의 답변을 기반으로 계정의 다른 것들 (utf-8, \ n 및 & nbsp;)을 기반으로 다른 버전을 얻었으며, wp와 함께 사용하는 경우 wordpress shortcodes를 주석 처리하는 줄도 제거했습니다.

    좋아, 그래서 위의 답변을 기반으로 계정의 다른 것들 (utf-8, \ n 및 & nbsp;)을 기반으로 다른 버전을 얻었으며, wp와 함께 사용하는 경우 wordpress shortcodes를 주석 처리하는 줄도 제거했습니다.

    function neatest_trim($content, $chars) 
      if (strlen($content) > $chars) 
      {
        $content = str_replace('&nbsp;', ' ', $content);
        $content = str_replace("\n", '', $content);
        // use with wordpress    
        //$content = strip_tags(strip_shortcodes(trim($content)));
        $content = strip_tags(trim($content));
        $content = preg_replace('/\s+?(\S+)?$/', '', mb_substr($content, 0, $chars));
    
        $content = trim($content) . '...';
        return $content;
      }
    
  13. ==============================

    13.

    /*
    Cut the string without breaking any words, UTF-8 aware 
    * param string $str The text string to split
    * param integer $start The start position, defaults to 0
    * param integer $words The number of words to extract, defaults to 15
    */
    function wordCutString($str, $start = 0, $words = 15 ) {
        $arr = preg_split("/[\s]+/",  $str, $words+1);
        $arr = array_slice($arr, $start, $words);
        return join(' ', $arr);
    }
    

    용법:

    $input = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna liqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.';
    echo wordCutString($input, 0, 10); 
    

    그러면 처음 10 단어가 출력됩니다.

    preg_split 함수는 문자열을 하위 문자열로 분할하는 데 사용됩니다. 문자열이 분할되는 경계는 정규식 패턴을 사용하여 지정됩니다.

    preg_split 함수는 4 개의 매개 변수를 사용하지만 처음 세 개는 현재 우리와 관련이 있습니다.

    첫 번째 매개 변수 - 패턴 첫 번째 매개 변수는 문자열을 따라 분할 할 정규식 패턴입니다. 이 경우 문자열을 단어 경계로 분할하려고합니다. 따라서 공백, 탭, 캐리지 리턴 및 줄 바꿈과 같은 공백 문자와 일치하는 미리 정의 된 문자 클래스 \ s를 사용합니다.

    두 번째 매개 변수 - 입력 문자열 두 번째 매개 변수는 분할하려는 긴 텍스트 문자열입니다.

    세 번째 매개 변수 - 한도 세 번째 매개 변수는 반환되어야하는 하위 문자열 수를 지정합니다. 한계를 n으로 설정하면 preg_split은 n 개의 요소 배열을 반환합니다. 첫 번째 n-1 요소에는 하위 문자열이 포함됩니다. 마지막 (n 번째) 요소에는 나머지 문자열이 포함됩니다.

  14. ==============================

    14.@ Justin Poliey의 정규식을 기반으로 :

    @ Justin Poliey의 정규식을 기반으로 :

    // Trim very long text to 120 characters. Add an ellipsis if the text is trimmed.
    if(strlen($very_long_text) > 120) {
      $matches = array();
      preg_match("/^(.{1,120})[\s]/i", $very_long_text, $matches);
      $trimmed_text = $matches[0]. '...';
    }
    
  15. ==============================

    15.이것은 mattmac의 대답에 대한 작은 수정입니다 :

    이것은 mattmac의 대답에 대한 작은 수정입니다 :

    preg_replace('/\s+?(\S+)?$/', '', substr($string . ' ', 0, 201));
    

    유일한 차이점은 $ string의 끝에 공백을 추가하는 것입니다. 이렇게하면 ReX357의 설명에 따라 마지막 단어가 잘리지 않습니다.

    나는 코멘트로 이것을 추가하기에 충분한 rep 지점이 없다.

  16. ==============================

    16.나는 당신이 원하는 것을 거의 수행하는 함수를 가지고있다. 만약 약간의 편집을한다면, 정확히 맞을 것이다.

    나는 당신이 원하는 것을 거의 수행하는 함수를 가지고있다. 만약 약간의 편집을한다면, 정확히 맞을 것이다.

    <?php
    function stripByWords($string,$length,$delimiter = '<br>') {
        $words_array = explode(" ",$string);
        $strlen = 0;
        $return = '';
        foreach($words_array as $word) {
            $strlen += mb_strlen($word,'utf8');
            $return .= $word." ";
            if($strlen >= $length) {
                $strlen = 0;
                $return .= $delimiter;
            }
        }
        return $return;
    }
    ?>
    
  17. ==============================

    17.이것은 내가 어떻게 그랬 :

    이것은 내가 어떻게 그랬 :

    $string = "I appreciate your service & idea to provide the branded toys at a fair rent price. This is really a wonderful to watch the kid not just playing with variety of toys but learning faster compare to the other kids who are not using the BooksandBeyond service. We wish you all the best";
    
    print_r(substr($string, 0, strpos(wordwrap($string, 250), "\n")));
    
  18. ==============================

    18.나는 이것이 오래된 것을 알고 있지만 ...

    나는 이것이 오래된 것을 알고 있지만 ...

    function _truncate($str, $limit) {
        if(strlen($str) < $limit)
            return $str;
        $uid = uniqid();
        return array_shift(explode($uid, wordwrap($str, $limit, $uid)));
    }
    
  19. ==============================

    19.나는 이것을 전에 사용했다.

    나는 이것을 전에 사용했다.

    <?php
        $your_desired_width = 200;
        $string = $var->content;
        if (strlen($string) > $your_desired_width) {
            $string = wordwrap($string, $your_desired_width);
            $string = substr($string, 0, strpos($string, "\n")) . " More...";
        }
        echo $string;
    ?>
    
  20. ==============================

    20.substr과 비슷한 함수를 만들고 @Dave라는 아이디어를 사용합니다.

    substr과 비슷한 함수를 만들고 @Dave라는 아이디어를 사용합니다.

    function substr_full_word($str, $start, $end){
        $pos_ini = ($start == 0) ? $start : stripos(substr($str, $start, $end), ' ') + $start;
        if(strlen($str) > $end){ $pos_end = strrpos(substr($str, 0, ($end + 1)), ' '); } // IF STRING SIZE IS LESSER THAN END
        if(empty($pos_end)){ $pos_end = $end; } // FALLBACK
        return substr($str, $pos_ini, $pos_end);
    }
    

    Ps .: 전장 절단은 substr보다 작을 수 있습니다.

  21. ==============================

    21.공백없이 문자열을 처리하기 위해 Dave와 AmalMurali의 코드에 IF / ELSEIF 문을 추가했습니다.

    공백없이 문자열을 처리하기 위해 Dave와 AmalMurali의 코드에 IF / ELSEIF 문을 추가했습니다.

    if ((strpos($string, ' ') !== false) && (strlen($string) > 200)) { 
        $WidgetText = substr($string, 0, strrpos(substr($string, 0, 200), ' ')); 
    } 
    elseif (strlen($string) > 200) {
        $WidgetText = substr($string, 0, 200);
    }
    
  22. ==============================

    22.나는 이것이 이것을하는 가장 쉬운 방법이라고 생각 :

    나는 이것이 이것을하는 가장 쉬운 방법이라고 생각 :

    $lines = explode('♦♣♠',wordwrap($string, $length, '♦♣♠'));
    $newstring = $lines[0] . ' &bull; &bull; &bull;';
    

    특수 문자를 사용하여 텍스트를 분할하고 잘라냅니다.

  23. ==============================

    23.나는이 작품을 찾는다 :

    나는이 작품을 찾는다 :

    함수 abbreviate_string_to_whole_word ($ string, $ max_length, $ buffer) {

    if (strlen($string)>$max_length) {
        $string_cropped=substr($string,0,$max_length-$buffer);
        $last_space=strrpos($string_cropped, " ");
        if ($last_space>0) {
            $string_cropped=substr($string_cropped,0,$last_space);
        }
        $abbreviated_string=$string_cropped."&nbsp;...";
    }
    else {
        $abbreviated_string=$string;
    }
    
    return $abbreviated_string;
    

    }

    버퍼를 사용하면 반환 된 문자열의 길이를 조정할 수 있습니다.

  24. ==============================

    24.여기에서 이것을 시도 할 수 있습니다.

    여기에서 이것을 시도 할 수 있습니다.

    substr( $str, 0, strpos($str, ' ', 200) ); 
    
  25. ==============================

    25.누군가가 도움이 될 수 있습니다.

    누군가가 도움이 될 수 있습니다.

    <?php
    
        $string = "Your line of text";
        $spl = preg_match("/([, \.\d\-''\"\"_()]*\w+[, \.\d\-''\"\"_()]*){50}/", $string, $matches);
        if (isset($matches[0])) {
            $matches[0] .= "...";
            echo "<br />" . $matches[0];
        } else {
            echo "<br />" . $string;
        }
    
    ?>
    
  26. from https://stackoverflow.com/questions/79960/how-to-truncate-a-string-in-php-to-the-word-closest-to-a-certain-number-of-chara by cc-by-sa and MIT license