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

PHP 判斷中英文字符:編碼感知的正則與多位元組字串處理

     編輯:PHP 相關知識

PHP 判斷字串是否包含中文,關鍵在於理解編碼與正則表達式的 Unicode 屬性支援。本文詳細比較 GBK/UTF-8 環境下的判斷方法,提供現代最佳實踐。

編碼背景知識

編碼中文範圍英文/數字PHP 內部處理
GBK/GB23120x8140-0xFEFE (雙位元組)0x00-0x7F (單位元組)不支援,需 iconv/mbstring
UTF-8U+4E00-U+9FFF (CJK 統一表意文字)U+0000-U+007F (ASCII)原生支援 (PHP 7+)

現代最佳做法:Unicode 正則屬性 (PHP 7+、PCRE 8.1+)

<?php
function hasChinese(string $str): bool {
    // \p{Han} 匹配所有漢字(CJK 統一表意文字)
    return (bool)preg_match('/\p{Han}/u', $str);
}

function isAllChinese(string $str): bool {
    // 全字串皆為漢字
    return (bool)preg_match('/^\p{Han}+$/u', $str);
}

function hasEnglish(string $str): bool {
    // \p{Latin} 或 ASCII 範圍
    return (bool)preg_match('/[A-Za-z]/', $str);
}

function isAllEnglish(string $str): bool {
    return (bool)preg_match('/^[A-Za-z0-9\s]+$/', $str);
}

// 測試
var_dump(hasChinese('Hello 世界'));      // true
var_dump(isAllChinese('你好世界'));       // true
var_dump(hasChinese('Hello World'));      // false
var_dump(isAllEnglish('Hello World'));    // true
?>

傳統 UTF-8 正則(不依賴 Unicode 屬性)

<?php
// UTF-8 中文範圍:\x{E4}\x{B8}\x{80} - \x{E9}\x{BE}\x{8F} (U+4E00-U+9FFF)
function hasChineseLegacy(string $str): bool {
    return (bool)preg_match('/[\x{4e00}-\x{9fff}]/u', $str);
}

// 更完整範圍(含擴展區)
function hasChineseFull(string $str): bool {
    return (bool)preg_match(
        '/[\x{3400}-\x{4dbf}\x{4e00}-\x{9fff}\x{f900}-\x{faff}\x{20000}-\x{2a6df}\x{2a700}-\x{2b73f}\x{2b740}-\x{2b81f}\x{2b820}-\x{2ceaf}]/u',
        $str
    );
}
?>

GBK/GB2312 環境處理(舊專案維護)

<?php
function hasChineseGbk(string $str): bool {
    // GBK 中文雙位元組高位元組 0x81-0xFE,低位元組 0x40-0xFE (排除 0x7F)
    // 簡化檢測:檢查是否有高位元組 (>= 0x80)
    return (bool)preg_match('/[\x80-\xFF]/', $str);
}

// 較精確(需 iconv 轉碼後判斷)
function hasChineseGbkAccurate(string $str): bool {
    $utf8 = @iconv('GBK', 'UTF-8//IGNORE', $str);
    return $utf8 !== false && hasChinese($utf8);
}
?>

mbstring 多位元組字串函數方案

<?php
// 逐字符檢查(效能較差但直觀)
function hasChineseMb(string $str): bool {
    $len = mb_strlen($str, 'UTF-8');
    for ($i = 0; $i < $len; $i++) {
        $char = mb_substr($str, $i, 1, 'UTF-8');
        $code = mb_ord($char, 'UTF-8');
        if ($code >= 0x4E00 && $code <= 0x9FFF) return true;
    }
    return false;
}

// 統計中英文字符數
function countCharTypes(string $str): array {
    $chinese = $english = $digit = $other = 0;
    $len = mb_strlen($str, 'UTF-8');
    for ($i = 0; $i < $len; $i++) {
        $char = mb_substr($str, $i, 1, 'UTF-8');
        $code = mb_ord($char, 'UTF-8');
        if ($code >= 0x4E00 && $code <= 0x9FFF) $chinese++;
        elseif ($code >= 0x41 && $code <= 0x5A) $english++; // A-Z
        elseif ($code >= 0x61 && $code <= 0x7A) $english++; // a-z
        elseif ($code >= 0x30 && $code <= 0x39) $digit++;
        else $other++;
    }
    return compact('chinese', 'english', 'digit', 'other');
}
?>

效能比較與選型建議

方法效能準確度相依性推薦場景
preg_match \p{Han}快高 (Unicode 標準)PCRE 8.1+現代專案首選
preg_match 範圍快中 (需維護範圍)PCRE + u 修飾符舊版 PHP 相容
mbstring 逐字慢最高 (可自訂邏輯)mbstring 擴展需統計/複雜判斷
GBK 高位元組最快低 (誤判日文/符號)無極舊專案維護

實務應用:使用者輸入驗證

<?php
function validateUsername(string $username): array {
    $errors = [];
    
    if (mb_strlen($username, 'UTF-8') < 2) {
        $errors[] = '長度至少 2 字符';
    }
    if (mb_strlen($username, 'UTF-8') > 20) {
        $errors[] = '長度不超過 20 字符';
    }
    if (!preg_match('/^[\p{Han}\p{Latin}\p{N}_]+$/u', $username)) {
        $errors[] = '僅允許中文、英文、數字、底線';
    }
    if (preg_match('/^\d+$/', $username)) {
        $errors[] = '不能純數字';
    }
    
    return ['valid' => empty($errors), 'errors' => $errors];
}
?>

核心原則:專案統一使用 UTF-8,配合 /\p{Han}/u 正則可解決 99% 中文判斷需求,避免編碼轉換帶來的錯誤與效能損耗。

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