php去掉多字节字符,PHP 面试题 - 如果没有 mb 系列函数,如何切割多字节字符串...
需求
如果需要將可能含有中文的字符串進行拆分成數組,我們下面以 utf-8 編碼為例。
解決方案一
我習慣的方法可能是: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));
}
var_export($array);
假如我們沒裝mb擴展怎么辦?
解決方案二
今天看到一份代碼,別人是這么寫的:/*
* 將可能含有中文的字符串進行拆分成數組
*/
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 ~ 1271 字節
192 ~ 2232 字節
224 ~ 2393 字節
240 ~ 2474 字節
為什么呢?
Unicode
Unicode 只是一個符號集,它只規定了符號的二進制代碼,卻沒有規定這個二進制代碼應該如何存儲。
UTF-8
UTF-8 就是在互聯網上使用最廣的一種 Unicode 的實現方式。UTF-8 最大的一個特點,就是它是一種變長的編碼方式。它可以使用1~4個字節表示一個符號,根據不同的符號而變化字節長度。
UTF-8 的編碼規則很簡單,只有二條:對于單字節的符號,字節的第一位設為0,后面7位為這個符號的 Unicode 碼。因此對于英語字母,UTF-8 編碼和 ASCII 碼是相同的(能容納0~127)。
對于n字節的符號(n > 1),第一個字節的前n位都設為1,第n + 1位設為0,后面字節的前兩位一律設為10。剩下的沒有提及的二進制位,全部為這個符號的 Unicode 碼。
下表總結了編碼規則,字母x表示可用編碼的位:Unicode 符號范圍(十六進制)UTF-8 編碼方式(二進制)UTF-8 首字節范圍0000 0000-0000 007F0xxxxxxx0 ~ 127
0000 0080-0000 07FF110xxxxx 10xxxxxx(128+64) ~ (255-32) 也就是 192 ~ 223
0000 0800-0000 FFFF1110xxxx 10xxxxxx 10xxxxxx(128+64+32) ~ (255-16) 也就是 224 ~ 239
0001 0000-0010 FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx(128+64+32+16) ~ (255-8) 也就是 240 ~ 247
想必看了這個表,大家就能明白了吧。
總結
以上是生活随笔為你收集整理的php去掉多字节字符,PHP 面试题 - 如果没有 mb 系列函数,如何切割多字节字符串...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 特斯拉“车顶事件”核心成员被判道歉赔偿
- 下一篇: 中国首个全球首富或是他?媒体称达成这一目