ホームページ >バックエンド開発 >PHPチュートリアル >文字化けを発生させずに PHP の中国語文字列を切り詰める問題の解決策

文字化けを発生させずに PHP の中国語文字列を切り詰める問題の解決策

WBOY
WBOYオリジナル
2016-07-25 09:07:24835ブラウズ
  1. function substring($str, $start, $length){ //文字列インターセプト関数を使用する方が良いです
  2. $len = $length;
  3. if($length < 0) {
  4. $str = strrev($str);
  5. $len = -$length;
  6. }
  7. $len= ($len < strlen($str)) $len : strlen($str);
  8. $tmpstr = "" ;
  9. for ($i= $start; $i < $len; $i ++)
  10. {
  11. if (ord(substr($str, $i, 1)) > 0xa0)
  12. {
  13. $ tmpstr . = substr($str, $i, 2);
  14. $i++;
  15. } else {
  16. $tmpstr .= substr($str, $i, 1);
  17. }
  18. }
  19. if($length < 0 ) $ tmpstr = strrev($tmpstr);
  20. return $tmpstr;
  21. }
  22. ?>
コードをコピー

使用例:

  1. $str1 = '私は英語のない比較的長い中国語の文字列です';

  2. $str2 = '私はインウェンを含む比較的長い中国語の文字列です' < ;/p>
  3. $len = strlen($str1);

  4. echo '
    '.$len; //return 28

  5. $len = strlen ( $str2);

  6. echo '
    '.$len; //return 29

  7. echo '
    '

  8. echo substring($str1, 0 , 11);
  9. echo '
    ';
  10. echo 部分文字列($str2, 0, 11);
  11. echo '
    ';
  12. echo 部分文字列($str1, 16, 28); echo '
    ';
  13. echo substring($str2, 16, 29);
  14. ?>
コードをコピーします
結果は次のようになります。 28 29 私は比較の連続です 私は比較の連続です 英語を使わない中国語 インウェンと中国語

この関数は、たとえば、比較的長いファイル名を切り詰めるのに使用できますが、途中に... を追加したい場合は、次のようにすることができます。

    function formatName($str, $size){
  1. $len = strlen($str);
  2. if(strlen($str) > $size) {
  3. $part1 = 部分文字列($str, 0, $size / 2);
  4. $part2 = substring($str, $len - ($size/2), $len);
  5. $part1 "..." を返します。 } else {
  6. return $str;
  7. }
  8. }
  9. ?>
  10. コードをコピー
さらに、テストした結果、非常に効果が高い中国語の切り捨てソリューションをインターネット上で見つけました。

echo substr($str1,0,10).chr(0);
  • ?>
  • コードをコピー
  • 原理説明: chr(0) は null ではありません null は何も意味せず、chr(0) の値は 0 です。 16 進数で表すと 0x00、2 進数で表すと 00000000 chr(0)は何も表示されませんが、文字です。 漢字が切り詰められると、エンコード規則に従って、必ずその後ろにある他の文字を引き込んで漢字として解釈する必要があるため、文字化けが発生します。 0x81~0xffと0x00の値の組み合わせは常に「空」として表示されます この機能により、substrの結果の後にchr(0)を追加することで文字化けを防ぐことができます

    20120705 更新: 上記の方法は良いのですが、それでも時々文字化けが発生し、原因はまだ究明されていません。ただし、UTF8 文字テキストに対して試行およびテストされている次の方法を使用できます。 注: この方法では、漢字は 1 単位の長さとして計算され、英語の 1 文字は 1 単位の長さとして計算されるため、切り捨ての際の長さの設定に注意する必要があります。 長さの計算方法:

    1. function strlen_UTF8($str)
    2. {
    3. $len = strlen($str);
    4. $n = 0;
    5. for($i = 0; $i < $len; $i++) {
    6. $x = substr($str, $i, 1);
    7. $a = Base_convert(ord($x), 10, 2);
    8. $a = substr('00000000' .$a, -8);
    9. if (substr($a, 0, 1) == 0) {
    10. }elseif (substr($a, 0, 3) == 110) {
    11. $i += 1;
    12. }elseif (substr($a, 0, 4) == 1110) {
    13. $i += 2;
    14. }
    15. $n++;
    16. }
    17. return $n;
    18. } // End strlen_UTF8;

    19. ///文字列切り捨て関数:

    20. function subString_UTF8($str, $start, $lenth)
    21. {
    22. $len = strlen($str);
    23. $r = array();
    24. $n = 0 ;
    25. $m = 0;
    26. for($i = 0; $i $x = substr($str, $i, 1);
    27. $a = Base_convert(ord( $ x), 10, 2);
    28. $a = substr('00000000'.$a, -8);
    29. if ($n < $start){
    30. if (substr($a, 0, 1) = = 0) {
    31. }elseif (substr($a, 0, 3) == 110) {
    32. $i += 1;
    33. }elseif (substr($a, 0, 4) == 1110) {
    34. $i + = 2;
    35. }
    36. $n++;
    37. }else{
    38. if (substr($a, 0, 1) == 0) {
    39. $r[ ] = substr($str, $i, 1);
    40. } elseif (substr($a, 0, 3) == 110) {
    41. $r[ ] = substr($str, $i, 2);
    42. $i += 1;
    43. }elseif (substr($a, 0 , 4) == 1110) {
    44. $r[ ] = substr($str, $i, 3);
    45. $i += 2;
    46. }else{
    47. $r[ ] = '';
    48. }
    49. if ( + +$m >= $lenth){
    50. Break;
    51. }
    52. }
    53. }
    54. return join($r);
    55. } // End subString_UTF8;

    56. // 使用方法と以前に紹介したものと同じで、たとえば、formatName は次のように実装できます (これには、中国語の文字の長さに対して若干の最適化が施されています):

    57. function formatName($str, $size){
    58. $len = strlen_UTF8($str) ;
    59. $one_len = strlen($str );
    60. $size = $size * 1.5 * $len / ($one_len);
    61. if(strlen_UTF8($str) > $size) {
    62. $part1 = subString_UTF8($str) , 0, $size / 2);
    63. $part2 = subString_UTF8($str, $len - ($size/2), $len);
    64. $part1 を返します。
    65. return $str;
    66. }
    67. }
    68. ?>

    コードをコピー


    声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。