Home  >  Article  >  Backend Development  >  PHP Chinese string truncation without garbled solution

PHP Chinese string truncation without garbled solution

高洛峰
高洛峰Original
2016-12-20 15:46:121297browse

A relatively easy-to-use string interception function:

function substring($str, $start, $length){ //比较好用字符串截取函数
  $len = $length;
  if($length < 0){
  $str = strrev($str);
  $len = -$length;
  }
  $len= ($len < strlen($str)) ? $len : strlen($str);
  $tmpstr = "";
  for ($i= $start; $i < $len; $i ++)
  {
      if (ord(substr($str, $i, 1)) > 0xa0)
      {
       $tmpstr .= substr($str, $i, 2);
       $i++;
      } else {
       $tmpstr .= substr($str, $i, 1);
      }
  }
  if($length < 0) $tmpstr = strrev($tmpstr);
  return $tmpstr;
}

Usage example:

$str1 = &#39;我是一串比较长的中文不带英文&#39;;
$str2 = &#39;我是一串比较长的中文带yingwen&#39;;
 
 
$len = strlen($str1);
echo &#39;<br />&#39;.$len; //return 28
 
$len = strlen($str2);
echo &#39;<br />&#39;.$len; //return 29
 
echo &#39;<br />&#39;; 
echo substring($str1, 0, 11); 
echo &#39;<br />&#39;;
echo substring($str2, 0, 11);   
echo &#39;<br />&#39;;
echo substring($str1, 16, 28); 
echo &#39;<br />&#39;;
echo substring($str2, 16, 29);

The result shows:

28
29
I am a string of comparisons
I am a string of comparisons
Chinese without English
Chinese with yingwen

This function is very useful. For example, it is used to truncate a relatively long file name, but if you want to add... in the middle, you can do it like this:

function formatName($str, $size){
  $len = strlen($str);
  if(strlen($str) > $size) {
    $part1 = substring($str, 0, $size / 2);
    $part2 = substring($str, $len - ($size/2), $len);
    return $part1 . "..." . $part2;
  } else {
    return $str;
  }
}

In addition, I saw a super simple Chinese truncation solution on the Internet. I tried it and it worked well:

echo substr($str1,0,10).chr(0);

Explanation of the principle:

chr(0 ) is not null
07null means nothing, and the value of chr(0) is 0. Expressed in hexadecimal it is 0x00, expressed in binary it is 00000000
08 Although chr(0) will not display anything, it is a character.
09 When Chinese characters are truncated, according to the encoding rules, they always have to pull in other characters behind them as Chinese characters for interpretation. This is the reason why garbled characters appear. The combination of values ​​0x81 to 0xff and 0x00 is always displayed as "empty"
10According to this feature, adding a chr(0) after the substr result can prevent garbled characters

------ -----------------------

20120705 update:

Although the above method is good, you still encounter garbled characters occasionally, and the reason is not yet understood. However, you can use the following method, which has been tried and tested with UTF8 character text.
Note: In this method, Chinese characters are calculated as 1 unit length, and one English letter is 1 unit length, so you need to pay attention to the length setting when truncating.
Method for calculating length:

function strlen_UTF8($str)
{
  $len = strlen($str);
  $n = 0;
  for($i = 0; $i < $len; $i++) {
    $x = substr($str, $i, 1);
    $a = base_convert(ord($x), 10, 2);
    $a = substr(&#39;00000000&#39;.$a, -8);
    if (substr($a, 0, 1) == 0) {
    }elseif (substr($a, 0, 3) == 110) {
      $i += 1;
    }elseif (substr($a, 0, 4) == 1110) {
      $i += 2;
    }
    $n++;
  }
  return $n;
} // End strlen_UTF8;

String truncation function:

function subString_UTF8($str, $start, $lenth)
  {
    $len = strlen($str);
    $r = array();
    $n = 0;
    $m = 0;
    for($i = 0; $i < $len; $i++) {
      $x = substr($str, $i, 1);
      $a = base_convert(ord($x), 10, 2);
      $a = substr(&#39;00000000&#39;.$a, -8);
      if ($n < $start){
        if (substr($a, 0, 1) == 0) {
        }elseif (substr($a, 0, 3) == 110) {
          $i += 1;
        }elseif (substr($a, 0, 4) == 1110) {
          $i += 2;
        }
        $n++;
      }else{
        if (substr($a, 0, 1) == 0) {
          $r[ ] = substr($str, $i, 1);
        }elseif (substr($a, 0, 3) == 110) {
          $r[ ] = substr($str, $i, 2);
          $i += 1;
        }elseif (substr($a, 0, 4) == 1110) {
          $r[ ] = substr($str, $i, 3);
          $i += 2;
        }else{
          $r[ ] = &#39;&#39;;
        }
        if (++$m >= $lenth){
          break;
        }
      }
    }
    return join($r);
  } // End subString_UTF8;

The usage method is the same as introduced before. For example, formatName can be implemented as follows (this has a small optimization for the length of Chinese characters):

function formatName($str, $size){
 $len = strlen_UTF8($str);
 $one_len = strlen($str);
 $size = $size * 1.5 * $len / ($one_len);
 if(strlen_UTF8($str) > $size) {
  $part1 = subString_UTF8($str, 0, $size / 2);
  $part2 = subString_UTF8($str, $len - ($size/2), $len);
  return $part1 . "..." . $part2;
 } else {
  return $str;
 }
}

The above is the entire content of this article. I hope it will be helpful to everyone’s learning. I also hope that everyone will support the PHP Chinese website.

For more articles related to PHP Chinese string truncation without garbled code solutions, please pay attention to the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn