處理中文、日文、Emoji 等 Unicode 字符時,傳統 [\u4e00-\u9fa5] 僅覆蓋基本多文種平面(BMP)常用漢字,無法匹配擴展區漢字、生僻字、Emoji(補充平面 SMP)。需使用 PHP PCRE 的 Unicode 屬性語法。
\x{XXXX} 與 Unicode 屬性<?php
// 1. 直接指定碼點範圍(十六進制)
// 基本漢字區:U+4E00-U+9FA5
// 擴展 A:U+3400-U+4DBF
// 擴展 B:U+20000-U+2A6DF(需 PCRE 8.32+ 支持 >FFFF)
$pattern = '/[\x{4e00}-\x{9fa5}\x{3400}-\x{4dbf}]/u';
// 2. 使用 Unicode 字符屬性(推薦,語義化、自動覆蓋所有區塊)
// \p{Han}:所有漢字(含擴展區)
// \p{L}:所有字母
// \p{N}:所有數字
// \p{P}:所有標點
// \p{Script=Han}:漢字腳本(更精確)
$pattern = '/\p{Han}+/u'; // 匹配連續漢字
$pattern = '/[\p{Han}\p{L}\p{N}]+/u'; // 漢字+字母+數字
// 3. 匹配 Emoji(補充平面,U+10000+)
// \p{So}:其他符號(含 Emoji)
// 更精確:\p{Extended_Pictographic} (PCRE 10.32+)
$emojiPattern = '/\p{So}/u';
?>
<?php
$text = "Hello 世界 🌍 𠮷𠮷𠮷 Test123!";
// 1. 提取所有漢字(含生僻字 𠮷 U+20BB7)
preg_match_all('/\p{Han}+/u', $text, $matches);
var_dump($matches[0]); // ["世界", "𠮷𠮷𠮷"]
// 2. 移除所有 Emoji
$clean = preg_replace('/\p{So}/u', '', $text);
echo $clean; // "Hello 世界 𠮷𠮷𠮷 Test123!"
// 3. 只保留漢字、字母、數字、常用標點
$filtered = preg_replace('/[^\p{Han}\p{L}\p{N}\p{P}\s]/u', '', $text);
echo $filtered; // "Hello 世界 𠮷𠮷𠮷 Test123!"
// 4. 驗證純中文(含生僻字)
function isPureChinese($str) {
return (bool)preg_match('/^[\p{Han}]+$/u', $str);
}
var_dump(isPureChinese('世界𠮷')); // true
var_dump(isPureChinese('World')); // false
?>
u (PCRE_UTF8)必須在正則結尾加
u修飾符:
/\p{Han}/u✅ 正確按 Unicode 字符匹配
/\p{Han}/❌ 按字節匹配,會將多字節字符拆分,導致錯誤匹配或報錯
| 區塊名稱 | 碼點範圍 | 說明 |
|---|---|---|
| CJK 統一表意文字 | U+4E00 - U+9FFF | 常用漢字 20992 個 |
| CJK 統一表意文字擴展 A | U+3400 - U+4DBF | 生僻漢字 6592 個 |
| CJK 統一表意文字擴展 B | U+20000 - U+2A6DF | 極生僻漢字 42720 個 |
| CJK 兼容表意文字 | U+F900 - U+FAFF | 兼容字符 |
| CJK 符號和標點 | U+3000 - U+303F | 全角標點、空格等 |
| 半形及全形字符 | U+FF00 - U+FFEF | 全角字母數字符號 |
| Emoji / 補充符號和象形文字 | U+1F000 - U+1FAFF | 彩色表情符號 |
\x{FFFF}(BMP 內)。\x{10000} 以上碼點(補充平面,如 Emoji、擴展 B)。\p{Extended_Pictographic} 精確匹配 Emoji。檢查版本:php -r "echo PCRE_VERSION;"
/\p{Han}+/u(最語義化、覆蓋全)。/\p{So}/u 或 /\p{Extended_Pictographic}/u(新版)。/[\x{4e00}-\x{9fa5}\x{3400}-\x{4dbf}]/u。u 修飾符,否則按字節匹配必出錯。