检测Java中的任何组合字符

rog*_*ack 2 java regex unicode combining-marks

我正在寻找一种方法来检测java字符串中的字符是否是"组合字符".例如,

String khmerCombiningVowel = 
 new String(new byte[]{(byte) 0xe1,(byte) 0x9f,(byte) 0x80}, "UTF-8"); // unicode 17c0
Run Code Online (Sandbox Code Playgroud)

代表结合高棉元音符号.我尝试过"\\p{InCombiningDiacriticalMarks}" 正则表达式,但它似乎不适用于这些特殊的组合字符.或者即使有一些所有unicode组合字符块的综合列表,我也可以为它们制作一个正则表达式?

Adr*_*ard 5

根据用于检查Unicode中组合字符的算法,有许多用于组合字符的块.

Java有许多有用的功能,尝试:

String codePointStr = new String(new byte[]{(byte) 0xe1, (byte) 0x9f, (byte) 0x80}, "UTF-8"); // unicode 17c0
System.out.println(codePointStr.matches("\\p{Mc}"));
System.out.println(
    Character.COMBINING_SPACING_MARK == Character.getType(codePointStr.codePointAt(0)));
Run Code Online (Sandbox Code Playgroud)

(在两种情况下都打印为true)

在这种情况下,COMBINING_SPACING_MARK(和相关的正则表达式\p{gc=Mc})都引用Unicode类别 "Mark,Spacing Combining",它基本上是任何与前一个字符组合的字符,同时还会增加宽度.

其他可能有用的正则表达式:\p{M}适用于任何类型的标记.如果你想使用的字符getType()常量,您可以通过检查获得相同的行为,如果它的类型是COMBINING_SPACING_MARKENCLOSING_MARK,或NON_SPACING_MARK.

ENCLOSING_MARK是一个周围的角色,就像一个圆圈 - 也为它结合的角色增加了宽度.

NON_SPACING_MARK包括拉丁字母变音符号组合标记等(标记基本上位于顶部或下方,并且不向字符添加任何宽度).