PHP 8.3 中统计特定字符数应使用 preg_match_all 获取匹配次数,如 /\p{Han}/u 统计汉字;需先过滤再测长时用 preg_replace 清洗后配合 mb_strlen;复杂边界判断可结合 PREG_OFFSET_CAPTURE。

PHP 8.3 中判断字符串长度本身不需要正则,但若需「按特定规则限定长度」(比如只算中文、忽略空格/标点、或匹配某类字符的总长度),就常要结合正则预处理或校验。关键不是“用正则求长度”,而是“用正则筛选出目标字符,再统计其数量”。
用 preg_match_all 统计符合模式的字符数
这是最常用的方式:先用正则找出所有匹配的字符(或字节/码点),再用 count() 得到个数。
- 比如统计字符串中中文汉字个数(UTF-8):
$count = preg_match_all('/\p{Han}/u', $str, $matches);\p{Han}匹配 Unicode 汉字,/u启用 UTF-8 模式。 - 统计纯字母+数字的字符总数(忽略空格和符号):
$count = preg_match_all('/[a-zA-Z0-9]/', $str, $matches); - 注意:
preg_match_all返回的是匹配次数,不是字节长度;$matches[0]才是全部匹配项数组,可用来进一步分析。
先过滤再用 mb_strlen 或 strlen 测长度
如果目标是「去掉某些字符后看剩余内容的长度」,推荐先用 preg_replace 清洗,再用多字节安全函数测长。
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
- 例如:计算去除所有空白符(空格、换行、制表等)后的实际内容长度:
$clean = preg_replace('/\s+/u', '', $str);
$len = mb_strlen($clean, 'UTF-8'); - 又如:只保留中文、英文字母和数字,再算长度:
$keep = preg_replace('/[^\p{Han}a-zA-Z0-9]/u', '', $str);
$len = mb_strlen($keep, 'UTF-8');
这里[^\p{Han}a-zA-Z0-9]表示“非汉字、非字母、非数字”的字符,''替换为空,即删除。
用 preg_match 配合 PREG_OFFSET_CAPTURE 做边界长度判断
当需要「某个匹配内容在字符串中的位置和跨度」时,可用 PREG_OFFSET_CAPTURE 获取起始偏移与自身长度,间接参与长度逻辑判断。
立即学习“PHP免费学习笔记(深入)”;
- 例如:检查用户名是否以 2–4 位中文开头,且总长不超过 12 字符:
if (preg_match('/^(\p{Han}{2,4}).*/u', $name, $m) && mb_strlen($name, 'UTF-8') - 更精细的:获取匹配段的字节长度(用于调试或截断):
preg_match('/\p{Han}+/', $str, $m, PREG_OFFSET_CAPTURE);
if (!empty($m[0])) {
$matchedText = $m[0][0];
$length = mb_strlen($matchedText, 'UTF-8');
}
注意 mb_strlen 和 strlen 的区别,别混用
PHP 8.3 默认启用 mbstring,但函数行为仍取决于编码参数。正则(尤其带 /u)默认按 UTF-8 处理,所以后续长度计算务必用 mb_strlen($str, 'UTF-8'),否则中文会算错(strlen 返回字节数,一个汉字通常是 3 字节)。
- 错误示范:
$str = "你好abc";
echo strlen($str); // 输出 9(3+3+1+1+1)
echo mb_strlen($str); // 输出 5(正确字符数) - 正则匹配后若要取子串,也建议用
mb_substr而非substr,避免截断半个汉字。


















