在 Java 中判斷字符屬於中文標點還是英文標點,核心原理是利用字符編碼範圍:中文字符(含標點)通常佔用 2-4 字節 (UTF-16 char 無法直接判斷),需通過 Unicode 碼點範圍或字節長度區分。
public static boolean isChinesePunctuation(char c) {
int codePoint = (int) c;
// CJK 符號和標點區塊: 3000-303F
// 半形及全形形式區塊: FF00-FFEF (含全形英文標點)
return (codePoint >= 0x3000 && codePoint <= 0x303F) ||
(codePoint >= 0xFF00 && codePoint <= 0xFFEF);
}
public static boolean isEnglishPunctuation(char c) {
int codePoint = (int) c;
// ASCII 標點範圍 (非字母數字)
return (codePoint >= 0x21 && codePoint <= 0x2F) || // !"#$%&'()*+,-./
(codePoint >= 0x3A && codePoint <= 0x40) || // :;<=>?@
(codePoint >= 0x5B && codePoint <= 0x60) || // [\]^_`
(codePoint >= 0x7B && codePoint <= 0x7E); // {|}~
}
public static boolean isChineseChar(int codePoint) {
// 判斷是否為 CJK 統一表意文字
return Character.UnicodeBlock.of(codePoint) == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS;
}
public static boolean isPunctuation(int codePoint) {
return Character.getType(codePoint) == Character.START_PUNCTUATION ||
Character.getType(codePoint) == Character.END_PUNCTUATION ||
Character.getType(codePoint) == Character.CONNECTOR_PUNCTUATION ||
Character.getType(codePoint) == Character.DASH_PUNCTUATION ||
Character.getType(codePoint) == Character.OTHER_PUNCTUATION;
}
// 組合判斷
public static boolean isChinesePunctuation(int codePoint) {
return isPunctuation(codePoint) &&
(Character.UnicodeBlock.of(codePoint) == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION ||
Character.UnicodeBlock.of(codePoint) == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS);
}
// 注意:Java char 是 UTF-16 代碼單元,補充字符需用 codePoint
public static boolean isLikelyChinese(char c) {
// 簡易判斷:非 ASCII 視為中文 (含標點)
return c > 0x7F; // ASCII 範圍 0-127
}
// 更準確:獲取 UTF-8 字節長度
public static int utf8ByteLength(String str) {
return str.getBytes(StandardCharsets.UTF_8).length;
}
// 中文字符通常 3 字節,英文 1 字節
public static void countCharTypes(String str) {
int chineseCount = 0, englishCount = 0, chinesePunct = 0, englishPunct = 0, other = 0;
for (int i = 0; i < str.length(); ) {
int codePoint = str.codePointAt(i);
i += Character.charCount(codePoint); // 處理補充字符
if (Character.isLetter(codePoint)) {
if (isChineseChar(codePoint)) chineseCount++;
else englishCount++;
} else if (isChinesePunctuation(codePoint)) {
chinesePunct++;
} else if (isEnglishPunctuation((char)codePoint)) {
englishPunct++;
} else {
other++;
}
}
System.out.printf("中文字:%d 英文字:%d 中標:%d 英標:%d 其他:%d%n",
chineseCount, englishCount, chinesePunct, englishPunct, other);
}
codePointAt 和 Character.charCount 正確遍歷\\p{Punct} 匹配所有標點,但不區分中英