PHP计算中文字符串长度的方法详解:UTF-8与GBK编码处理

七月
七月
发布时间:2026-10-15 | 4人浏览过
原创

在使用 PHP 处理文本时,常遇到中英文混合或纯中文的字符串,直接调用 strlen 往往因为编码(UTF-8/GBK)占用字节数不同而得到错误的“字符数”。本文将解析底层原理,并提供基于 mbstring 扩展、正则表达式等多种准确的字符串长度计算方案。

为什么直接使用 strlen 计算中文长度不准确?

strlen() 函数统计的是字符串所占的字节(Byte)数,而非字符个数。不同编码格式下,英文与中文占用的字节数差异巨大:

  • UTF-8 编码:通常一个英文字符占 1 个字节,一个中文字符占 3 个字节(常见于大多数现代 Web 应用)。
  • GBK/GB2312 编码:通常一个英文字符占 1 个字节,一个中文字符占 2 个字节。

例如,在处理 UTF-8 编码的中文字符串时,如果用户输入 "Hello中国",strlen 返回的长度会是 5 + 6 = 11,这显然不符合直观上的字符计数预期。

准确计算字符串长度的推荐方案

第1步:使用 mbstring 扩展(推荐且最准确)

如果你使用的是包含中文内容的现代站点,强烈建议启用 PHP 的 mbstring 扩展。该扩展提供了多字节安全函数,能自动识别编码并返回正确的字符数量。

操作入口:确保服务器已安装并启用 php-mbstring 模块。

核心动作:使用 mb_strlen() 并指定编码参数。

// 获取字符串的字符数,指定编码为 UTF-8
$zhStr = '您好,中国!';
// $enStr = 'Hello!';

$charLen = mb_strlen($zhStr, 'UTF-8');
echo $charLen; // 输出:6 (即3个汉字+3个标点符号=6个字符单元)

// 获取字节数(等同于 strlen 但更安全)
$byteLen = mb_strlen($zhStr, 'current');

完成状态判断:执行结果等于实际可见的字符个数。

第2步:不依赖扩展时的正则匹配方案(UTF-8专用)

若环境受限无法开启 mbstring 扩展,可以使用 preg_match_all 将 UTF-8 字符串拆解为独立的字符单元。此方法仅适用于 UTF-8 编码。

操作入口:编写自定义辅助函数。

核心动作:
利用 /./us 正则表达式匹配所有 Unicode 字符单元。

$zhStr = '您好,中国!';
$str = 'Hello,中国!';

function utf8_strlen($string = null) {
    // /us: u代表修正PCRE默认行为按字节处理,s代表让点号(.)匹配包括换行符在内的所有字符
    preg_match_all("/.+/us", $string, $match);
    return count($match[0]);
}

echo utf8_strlen($zhStr); // 输出:6
echo utf8_strlen($str);   // 输出:9

重要参数:u 修饰符至关重要,否则 UTF-8 的多字节字符会被错误地拆分为多个单字节。

第3步:手动遍历 ASCII 值判断(兼容性最强)

如果连 pcre 扩展都不可用(极罕见),可以通过循环读取每个字节的 ASCII 值来判断是单字节字符还是多字节字符的开始。

操作入口:使用 ord() 和循环逻辑。

核心动作:
检查字节数值范围。大于 127 即为非 ASCII 字符(通常是中文)。根据 UTF-8 规范,第一个字节的大小决定了该字符后续跟随几个字节(3字节开头通常在 192-223 或 224-239 等区间)。

function get_char_count_utf8($str) {
    $count = 0;
    for ($i = 0; $i < strlen($str); $i++) {
        $value = ord($str[$i]);
        if ($value > 127) {
            $count++;
            // 跳过该字符剩余字节
            if ($value >= 224 && $value <= 239) $i += 2;
            elseif ($value >= 192 && $value <= 223) $i += 1;
        } else {
            $count++;
        }
    }
    return $count;
}

GBK 编码下的特殊处理

GBK 编码下每个中文字符固定占 2 个字节。虽然也可以用上述的正则方法(因为GBK也是单字节语言的一种变体,但需注意正则效率可能略低),但在传统 CMS 或遗留系统中,更常见的做法是直接除以 2,或者借助 mb_convert_encoding 先将 GBK 转为 UTF-8 再进行标准处理。

// GBK 环境下获取字符数
$gbk_str = '你好世界';
$len_byte = strlen($gbk_str); // 结果为 8
$len_char = round($len_byte / 2); // 结果为 4

总结与避坑指南

在处理涉及多语言的 Web 项目时,请务必遵循以下原则:

  1. 首选 mbstring:mb_strlen($str, 'UTF-8') 是行业标准做法,性能较好且不易出错。
  2. 统一编码:建议在数据库和应用程序层面统一使用 UTF-8 (UTF-8mb4),避免在代码中进行频繁的 GBK 转码。
  3. 注意正则细节:如果使用 /./s 处理 UTF-8,必须加上 u 标志,否则在包含 Emoji 或多字节组合字符时仍会报错或计算错误。

以上就是 PHP 计算字符串长度包含中文字符处理的详细内容,更多关于 PHP 字符串操作技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表