首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 中文字符串截取完整指南:多種編碼兼容方案匯總

     編輯:PHP 綜合知識

前言

在 PHP 開發中,中文字符串截取是常見需求,但因編碼差異(GB2312、UTF-8 等),直接使用 substr 會導致亂碼。本文匯總四種主流截取方案,涵蓋不同編碼場景,助你輕鬆應對多字節字符處理。

方案一:GB2312 編碼專用截取函數

針對 GB2312 編碼,利用 ord() 判斷字節高位(> 0xA0)識別雙字節漢字,逐字符拼接:

function mysubstr($str, $start, $len) {
    $tmpstr = '';
    $strlen = $start + $len;
    for ($i = 0; $i < $strlen; $i++) {
        if (ord(substr($str, $i, 1)) > 0xA0) {
            $tmpstr .= substr($str, $i, 2);
            $i++;
        } else {
            $tmpstr .= substr($str, $i, 1);
        }
    }
    return $tmpstr;
}

適用場景:舊系統維護、GB2312 編碼項目。

方案二:UTF-8 正則截取法

使用正則表達式匹配 UTF-8 多字節模式(ASCII 1 字節、雙字節、三字節等),配合 preg_replace 精準截取:

function utf8Substr($str, $from, $len) {
    return preg_replace(
        '#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'.$from.'}'.
        '((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'.$len.'}).*#s',
        '$1', $str
    );
}

優點:代碼簡潔;缺點:正則複雜,效能稍遜於逐字符解析。

方案三:雙編碼通用截取函數(推薦)

整合 UTF-8 與 GB2312 支援,通過 preg_match_all 將字符串拆分為字符陣列,再用 array_slice 截取,自動補充省略號:

function cut_str($string, $sublen, $start = 0, $code = 'UTF-8') {
    if ($code === 'UTF-8') {
        $pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/";
        preg_match_all($pa, $string, $t_string);
        $slice = array_slice($t_string[0], $start, $sublen);
        return count($t_string[0]) - $start > $sublen 
            ? join('', $slice) . '...' 
            : join('', $slice);
    } else { // GB2312
        $start *= 2; $sublen *= 2;
        $strlen = strlen($string);
        $tmpstr = '';
        for ($i = 0; $i < $strlen; $i++) {
            if ($i >= $start && $i < ($start + $sublen)) {
                $tmpstr .= ord(substr($string, $i, 1)) > 129 
                    ? substr($string, $i, 2) 
                    : substr($string, $i, 1);
            }
            if (ord(substr($string, $i, 1)) > 129) $i++;
        }
        return strlen($tmpstr) < $strlen ? $tmpstr . '...' : $tmpstr;
    }
}
// 測試
$str = "abcd需要截取的字符串";
echo cut_str($str, 8, 0, 'gb2312'); // 輸出:abcd需要截...

核心優勢:單一函數兼容雙編碼,邏輯清晰,生產環境推薦使用。

方案四:BugFree 專案實戰截取函數

源自 BugFree 開源項目,專為 UTF-8 設計,逐字符判斷字節長度(1~3 字節),支援可選省略號:

function sysSubStr($String, $Length, $Append = false) {
    if (strlen($String) <= $Length) return $String;
    $I = 0; $StringLast = [];
    while ($I < $Length) {
        $StringTMP = substr($String, $I, 1);
        if (ord($StringTMP) >= 224) { $StringTMP = substr($String, $I, 3); $I += 3; }
        elseif (ord($StringTMP) >= 192) { $StringTMP = substr($String, $I, 2); $I += 2; }
        else { $I++; }
        $StringLast[] = $StringTMP;
    }
    $StringLast = implode('', $StringLast);
    return $Append ? $StringLast . '...' : $StringLast;
}

總結與建議

  • 現代項目(UTF-8):優先使用方案三 cut_str 或 PHP 內建 mb_substr(需啟用 mbstring 擴展)。
  • 舊系統(GB2312):方案一或方案三的 GB2312 分支。
  • 效能敏感場景:避免正則方案,採用逐字符解析。

掌握這些方案,即可從容應對各類中文截取需求,告別亂碼困擾。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved