PHP 高级面试题 - 如果没有 mb 系列函数,如何切割多字节字符串
程序员文章站
2022-05-31 22:21:46
需求 如果需要将可能含有中文的字符串进行拆分成数组,我们下面以 utf-8 编码为例。 解决方案一 我习惯的方法可能是: mb_internal_encoding("UTF-8"); $str = "周梦康"; $array = []; for ($i=0,$l = mb_strlen($str); ......
需求
如果需要将可能含有中文的字符串进行拆分成数组,我们下面以 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, "utf-8")); } 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码值。
切割规则如下
为什么呢?
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
表示可用编码的位:
想必看了这个表,大家就能明白了吧。
以上是文章全部内容,有需要学习交流的友人请加入交流群的咱们一起,有问题一起交流,一起进步!前提是你是学技术的。感谢阅读!