常見 [\u4e00-\u9fbb] 僅覆蓋 CJK 統一漢字基本區,**遺漏**:中文標點(。、!?)、全寬字符、擴展區稀有漢字、康熙部首、漢字筆順等。
public final class ChineseCharDetector {
private ChineseCharDetector() {}
/** 單字符判斷:覆蓋所有中文相關 Unicode Block */
public static boolean isChinese(char c) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS // 基本區
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS // 兼容區
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A // 擴展A
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B // 擴展B
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION // 標點符號
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS // 全半寬形式
|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION; // 通用標點(含部分中文引號)
}
/** 字符串判斷:含任一中文字符即返回 true */
public static boolean containsChinese(String str) {
if (str == null || str.isEmpty()) return false;
for (char c : str.toCharArray()) {
if (isChinese(c)) return true;
}
return false;
}
/** 統計中文字符數量 */
public static int countChinese(String str) {
if (str == null) return 0;
int cnt = 0;
for (char c : str.toCharArray()) if (isChinese(c)) cnt++;
return cnt;
}
}
String[] testCases = {
"Hello World", // false
"你好世界", // true
"!@#¥%……&*()", // true (中文標點)
"abc123", // true (全寬字符)
"𠮷野屋", // true (擴展B字符)
"😀🎉" // false (Emoji)
};
for (String s : testCases) {
System.out.printf("%-15s → %b%n", "\"" + s + "\"", ChineseCharDetector.containsChinese(s));
}
輸出:
"Hello World" → false
"你好世界" → true
"!@#¥%……&*()" → true
"abc123" → true
"𠮷野屋" → true
"😀🎉" → false
利用 \p{IsBlockName} 語法:
// 僅作為參考,Block 名稱需精確匹配
Pattern p = Pattern.compile("[\\p{IsCJK_Unified_Ideographs}" +
"\\p{IsCJK_Symbols_and_Punctuation}" +
"\\p{IsHalfwidth_and_Fullwidth_Forms}]");
但 Block 名稱跨 JDK 版本可能變動,**推薦使用 `Character.UnicodeBlock` 枚舉方式,類型安全、編譯期檢查、無字符串拼接錯誤風險。**
採用 Unicode Block 官方分類,一次覆蓋所有中文相關字符集,避免正則維護噩夢。