在 GBK 編碼環境下,使用 explode('|', $str) 分割包含特定漢字的字符串時會產生錯誤結果。例如:
$result = explode('|', '滕華弢|海青'); // 錯誤分割
原因在於「弢」字的 GBK 編碼為 0x8F7C,其低位字節 0x7C 恰好等同於 ASCII 字符「|」(0x7C),導致 explode 錯誤地在漢字內部進行分割。
GBK 編碼範圍為 0x8140-0xFEFE,所有低位字節為 0x7C 的字符均會觸發此問題,常見字符包括:
<?php
$str = '滕華弢|海青';
$utf8 = iconv('GBK', 'UTF-8', $str);
$parts = explode('|', $utf8);
$result = array_map(function($v) {
return iconv('UTF-8', 'GBK', $v);
}, $parts);
?>
優點:邏輯簡單,適用於所有分隔符
缺點:雙重轉碼效能開銷大,不適合高頻操作
<?php
$gbk_str = '滕華弢|海青';
preg_match_all('/([\x81-\xfe][\x40-\xfe])+/', $gbk_str, $matches);
$result = $matches[0]; // 正確分割結果
?>
原理:GBK 雙字節字符高位範圍 0x81-0xFE,低位範圍 0x40-0xFE(排除 0x7F),正則直接匹配完整雙字節字符序列,繞過分隔符衝突。
優點:無需轉碼,執行速度快,記憶體佔用少
適用場景:固定分隔符、大數據量處理
<?php
function gbk_explode($delimiter, $string) {
$result = [];
$current = '';
$len = strlen($string);
for ($i = 0; $i < $len; $i++) {
$char = $string[$i];
// 判斷是否為 GBK 高位字節
if (ord($char) >= 0x81 && ord($char) <= 0xFE) {
$current .= $char . $string[++$i]; // 取雙字節
} elseif ($char === $delimiter) {
$result[] = $current;
$current = '';
} else {
$current .= $char;
}
}
$result[] = $current;
return $result;
}
?>
utf8mb4 字符集gbk_explode() 為通用工具函數,統一替換原生 explode()GBK 編碼下的分割亂碼本質是「單字節分隔符與雙字節字符低位衝突」。正則匹配法 preg_match_all('/([\x81-\xfe][\x40-\xfe])+/') 是效能與兼容性的最佳平衡點,建議在存量 GBK 專案中採用。