UTF-8 編碼中,漢字等常用字符佔3個字節,字節範圍固定:
0xE4 (228) ~ 0xE9 (233)0x80 (128) ~ 0xBF (191)利用此規律,構造正則表達式匹配字符串中是否存在符合「3字節UTF-8漢字模式」的片段,即可判定是否為UTF-8編碼。
function is_utf8($str) {
// 匹配開頭、結尾或連續2組以上的 3字節UTF-8漢字模式
$pattern = '/^([\xE4-\xE9][\x80-\xBF][\x80-\xBF]){1}$'
. '|^([\xE4-\xE9][\x80-\xBF][\x80-\xBF]){1}'
. '|([\xE4-\xE9][\x80-\xBF][\x80-\xBF]){1}$'
. '|([\xE4-\xE9][\x80-\xBF][\x80-\xBF]){2,}/';
return (bool)preg_match($pattern, $str);
}
^([\xE4-\xE9][\x80-\xBF][\x80-\xBF]){1}$:整個字符串**恰好是一個**3字節UTF-8字符。^([\xE4-\xE9][\x80-\xBF][\x80-\xBF]){1}:字符串**開頭**有一個3字節UTF-8字符。([\xE4-\xE9][\x80-\xBF][\x80-\xBF]){1}$:字符串**結尾**有一個3字節UTF-8字符。([\xE4-\xE9][\x80-\xBF][\x80-\xBF]){2,}:字符串**中間**包含**連續兩個或以上**3字節UTF-8字符。四種情形任一滿足即返回 true,否則 false。
$test1 = "你好世界"; // UTF-8編碼
$test2 = "hello"; // 純ASCII
$test3 = "测试"; // UTF-8編碼
var_dump(is_utf8($test1)); // bool(true)
var_dump(is_utf8($test2)); // bool(false)
var_dump(is_utf8($test3)); // bool(true)
mb_check_encoding($str, 'UTF-8') 或 mb_detect_encoding(),準確率更高、覆蓋字符集更全。本文正則方案適合快速原型、簡單過濾、無mbstring擴展環境的場景。正規項目請優先使用 PHP 多字節字符串函數庫,保證編碼檢測的權威性與完備性。