PHP 高级面试题 - 如果没有 mb 系列函数,如何切割多字节字符串
作者:周梦康 原文:https://mengkang.net/1129.html
很多工程师在工作1~3年的时候最容易遇到瓶颈,不知道自己应该学习什么,面试总是吃闭门羹。那么 PHP 后面应该怎么学呢?安利一波我的系列直播 PHP 进阶之路
需求
如果需要将可能含有中文的字符串进行拆分成数组,我们下面以 utf-8 编码为例。
解决方案一
我习惯的方法可能是:
$str = "周梦康";
$array = [];
for ($i=0,$l = mb_strlen($str,"utf-8"); $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 ~ 127 |
1 字节 |
192 ~ 223 |
2 字节 |
224 ~ 239 |
3 字节 |
240 ~ 247 |
4 字节 |
为什么呢?
http://www.ruanyifeng.com/blog/2007/10/asciiunicodeand_utf-8.html https://segmentfault.com/a/1190000012692022 口语化叙述 utf-8 的来历
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 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 |
想必看了这个表,大家就能明白了吧。
觉得本文对你有帮助?请分享给更多人。
- HDUOJ----1181 变形课
- 正确的Win主机网站伪静态设置方法
- HDUOJ----(1084)What Is Your Grade?
- HDUOJ------(1272)小希的迷宫
- HDUOJ ---1269迷宫城堡
- HDUOJ---1213How Many Tables
- hduoj----(1033)Edge
- HDUOJ----(1031)Design T-Shirt
- HDUOJ----(1030)Delta-wave
- 身份切换脚本,免登入切换权限的利器
- HDUOJ---What Are You Talking About
- HDUOJ-----(1251)统计难题
- HDUOJ-----1541 Stars
- HDUOJ--------(1198)Farm Irrigation
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC