Skip to content

多字节字符串处理(MBString)

处理中文等多字节字符时,必须使用 MBString 扩展,否则会出现乱码或截断问题。

为什么要用 MB 函数

php
$str = "中文字符串";

echo strlen($str);       // 15(UTF-8 下每个中文3字节)
echo mb_strlen($str);    // 5(正确字符数)

echo substr($str, 0, 3);      // 乱码(截断了字节)
echo mb_substr($str, 0, 3);   // 中文(正确截取3个字符)

常用函数对比

单字节函数多字节函数说明
strlen()mb_strlen()字符串长度
substr()mb_substr()截取子串
strpos()mb_strpos()查找位置
strrpos()mb_strrpos()反向查找
strtolower()mb_strtolower()转小写
strtoupper()mb_strtoupper()转大写
substr_count()mb_substr_count()子串出现次数

基础用法

php
// 设置内部编码
mb_internal_encoding('UTF-8');

$str = "Hello 世界";

// 获取长度
echo mb_strlen($str);           // 8
echo mb_strlen($str, 'UTF-8');  // 显式指定编码

// 截取字符串
echo mb_substr($str, 6, 2);     // 世界

// 查找位置
echo mb_strpos($str, '世界');   // 6

// 大小写转换(支持中文拼音规则)
echo mb_strtoupper('hello');    // HELLO

// 分割字符串(类似 explode)
$chars = mb_str_split('中文测试', 1);  // ['中', '文', '测', '试']

编码转换

php
// 转换编码
$gbk = mb_convert_encoding("中文", 'GBK', 'UTF-8');
$utf8 = mb_convert_encoding($gbk, 'UTF-8', 'GBK');

// 自动检测编码
$encoding = mb_detect_encoding($str, ['UTF-8', 'GBK', 'ISO-8859-1']);
echo $encoding;

// 批量转换数组
$arr = ['中', '文'];
$converted = array_map(function($s) {
    return mb_convert_encoding($s, 'GBK', 'UTF-8');
}, $arr);

实用的中文处理函数

php
// 截取中文摘要(不截断字符)
function excerpt($text, $length = 100) {
    if (mb_strlen($text) <= $length) {
        return $text;
    }
    return mb_substr($text, 0, $length) . '...';
}

// 计算中英文混合的实际宽度(中文算2字符宽)
function mb_strwidth_cn($str) {
    $width = 0;
    for ($i = 0; $i < mb_strlen($str); $i++) {
        $char = mb_substr($str, $i, 1);
        // CJK 字符宽度为2
        $width += (preg_match('/[\x{4e00}-\x{9fa5}]/u', $char)) ? 2 : 1;
    }
    return $width;
}

// 按宽度截取(用于等宽字体对齐)
function mb_strimwidth_cn($str, $width) {
    $result = '';
    $currentWidth = 0;
    for ($i = 0; $i < mb_strlen($str); $i++) {
        $char = mb_substr($str, $i, 1);
        $charWidth = (preg_match('/[\x{4e00}-\x{9fa5}]/u', $char)) ? 2 : 1;
        if ($currentWidth + $charWidth > $width) {
            break;
        }
        $result .= $char;
        $currentWidth += $charWidth;
    }
    return $result;
}

正则表达式中的中文

php
// 匹配中文字符
preg_match('/[\x{4e00}-\x{9fa5}]+/u', '中文abc', $matches);

// 提取所有中文
preg_match_all('/[\x{4e00}-\x{9fa5}]/u', 'Hello 中文', $matches);
print_r($matches[0]);  // ['中', '文']

// 替换中文
$text = preg_replace('/[\x{4e00}-\x{9fa5}]+/u', '[中文]', '这是中文测试');
echo $text;  // [中文]

注意事项

  1. 始终设置 mb_internal_encoding('UTF-8')
  2. 数据库连接也要使用 UTF-8
  3. HTML 页面头部声明 <meta charset="UTF-8">
  4. 处理文件名等系统接口时可能需要转码

Binstork