PHPプレミアム面接問題-mbシリーズ関数がない場合、マルチバイト文字列を切断する方法

2743 ワード

需要
中国語を含む可能性のある文字列を配列に分割する必要がある場合は、utf-8符号化を例に挙げます.
ソリューション1
私が慣れている方法は、
mb_internal_encoding("UTF-8");

$str = "   ";

$array = [];
for ($i=0,$l = mb_strlen($str); $i < $l; $i++) { 
    array_push($array, mb_substr($str, $i, 1, "utf-8"));
}

var_export($array);

もし私たちがmb拡張子をインストールしていなかったらどうしますか?
ソリューション2
今日コードを見ました.他の人はこう書いています.
function str_split_utf8($str)  
{  
    $split = 1;  
    $array = array();  
    for ($i = 0; $i < strlen($str);) {  
        $value = ord($str[$i]);  
        if ($value > 127) {  
            if ($value >= 192 && $value <= 223) {  
                $split = 2;  
            } elseif ($value >= 224 && $value <= 239) {  
                $split = 3;  
            } elseif ($value >= 240 && $value <= 247) {  
                $split = 4;  
            }  
        } else {  
            $split = 1;  
        }  
        $key = null;  
        for ($j = 0; $j < $split; $j++, $i++) {  
            $key .= $str[$i];  
        }  
        array_push($array, $key);  
    }  
    return $array;  
}  

コード解読strlenはバイト数を計算し、$str[x]を直接使用すると、c言語のchar配列と文字列の習慣に従い、$strをバイトで読み取ることを示します.つまり、読み出すたびにデータのasciiコード値が255を超えることはできません.phpではordを用いてascii符号値を取得する.
カットルールは次のとおりです.
asciiコード範囲
カットオフセット
0 ~ 127
1バイト
192 ~ 223
2バイト
224 ~ 239
3バイト
240 ~ 247
4バイト
どうしてですか.
http://www.ruanyifeng.com/blo... https://segmentfault.com/a/11...口語化叙述utf-8の由来
Unicode
Unicodeはシンボルセットにすぎず、シンボルのバイナリコードのみを規定しているが、このバイナリコードがどのように格納されるべきかは規定されていない.
UTF-8
UTF-8はインターネット上で最も広く使われているUnicodeの実現方式である.UTF-8の最大の特徴は、長くなる符号化方式である.1~4バイトで1つのシンボルを表し、異なるシンボルに応じてバイト長を変化させることができる.
UTF-8の符号化規則は簡単で、2つしかありません.
  • は、1バイトのシンボルに対して、バイトの1番目のビットを0とし、後の7ビットをこのシンボルのUnicodeコードとする.したがって、英字ではUTF-8符号とASCII符号は同じである(0~127を収容できる).
  • nバイトの符号(n>1)について、1バイト目の前nビットはいずれも1、第n + 1ビットは0、後バイトの前2ビットは一律10とする.残りの言及されていないバイナリビットは、すべてこの記号のUnicodeコードである.

  • 次の表は、符号化ルールをまとめ、アルファベットxは、使用可能な符号化のビットを表す.
    Unicodeシンボル範囲(16進数)
    UTF-8符号化方式(バイナリ)
    UTF-8ヘッダ範囲
    0000 0000-0000 007F
    0xxxxxxx
    0 ~ 127
    0000 0080-0000 07FF
    110xxxxx 10xxxxxx
    (128+64)~(255-32)つまり192~223
    0000 0800-0000 FFFF
    1110xxxx 10xxxxxx 10xxxxxx
    (128+64+32)~(255-16)つまり224~239
    0001 0000-0010 FFFF
    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    (128+64+32+16)~(255-8)つまり240~247
    ぜひこの時計を見てみたいと思ったら、皆さんも分かるでしょう.
    ソース:https://segmentfault.com/a/1190000012710624