我打算规范化为 C 型,然后划分为“显示单位”,基本上是一个字形加上所有以下组合字符。现在,我只想处理基于拉丁语的脚本。
要确定一个代码点是否是一个组合字符,检查它是否在这些范围内就足够了吗?
- 组合变音符 (0300–036F)
- 组合变音符号补充 (1DC0–1DFF)
- 组合符号的变音符号 (20D0–20FF)
- 组合半分 (FE20–FE2F)
阿拉伯语、希伯来语和各种印度文字待定...
我打算规范化为 C 型,然后划分为“显示单位”,基本上是一个字形加上所有以下组合字符。现在,我只想处理基于拉丁语的脚本。
要确定一个代码点是否是一个组合字符,检查它是否在这些范围内就足够了吗?
阿拉伯语、希伯来语和各种印度文字待定...
这些是 Unicode 点的所有范围,其名称包含“组合”一词(例如301 COMBINING ACUTE ACCENT
):
300-36F
483-489
7EB-
7F3 135F
- 135F 1A7F-
1A7F 1B6B-1B73
1DC0-1DE6
1DFD-1DFF
20D0-20F0
2CEF-2CF1
2DE0-2DFF
3099-309A
A66F-A672
-A167C
-A67EFE
A67C-A67EFE
A6F0 FE26
101FD-101FD
1D165-1D169
1D16D-1D172
1D17B-1D182
1D185-1D18B
1D1AA-1D1AD
1D242-1D244
我使用 Python 脚本编译了这个列表,并使用了该unicodedata
模块。我不知道这到底是什么版本的 Unicode,但我认为它是最新的。
但是,我不知道您是否已经完成了严格意义上的“组合”字符,因为 Unicode 中也有“修饰符字母”等。
好的,我最近确实做了类似的事情。享受!
public static List<String> stringToCharacterWithCombiningChars(String fullText) {
Pattern splitWithCombiningChars = Pattern.compile("(\\p{M}+|\\P{M}\\p{M}*)"); // {M} is any kind of 'mark' http://stackoverflow.com/questions/29110887/detect-any-combining-character-in-java/29111105
Matcher matcher = splitWithCombiningChars.matcher(fullText);
ArrayList<String> outGoing = new ArrayList<>();
while(matcher.find()) {
outGoing.add(matcher.group());
}
return outGoing;
}
附带的(通过)单元测试是否对追随者有价值:https ://gist.github.com/rdp/0014de502f37abd64ffd
@lenz 的答案涵盖了大部分代码点,但有些缺失。下面是通过处理名称列表文件找到的范围列表。一些代码点COMBINING
在名称中有,但没有组合字符,例如Combining Grapheme Joiner (CGJ, 0x34f) [wiki]。正如维基百科文章中引用的那样:
它的名字用词不当,没有描述它的功能;该字符不加入字素。其目的是分隔不应被视为二合字母的字符。
处理列表时,发现了以下范围(和字符)。请注意与 lenz 的列表(略有不同)的那些用感叹号 (!) 表示。通常范围会稍微偏离,例如因为其中一个字符不在范围内,因此范围被“切成两半”:
0x300 - 0x34e !
0x350 - 0x36f !
0x483 - 0x487 !
0x591 - 0x5bd !
0x5bf !
0x5c1 - 0x5c2 !
0x5c4 - 0x5c5 !
0x5c7 !
0x610 - 0x61a !
0x64b - 0x65f !
0x670 !
0x6d6 - 0x6dc !
0x6df - 0x6e4 !
0x6e7 - 0x6e8 !
0x6ea - 0x6ed !
0x711 !
0x730 - 0x74a !
0x7eb - 0x7f3
0x816 - 0x819 !
0x81b - 0x823 !
0x825 - 0x827 !
0x829 - 0x82d !
0x859 - 0x85b !
0x8d4 - 0x8e1 !
0x8e3 - 0x8ff !
0x93c !
0x94d !
0x951 - 0x954 !
0x9bc !
0x9cd !
0xa3c !
0xa4d !
0xabc !
0xacd !
0xb3c !
0xb4d !
0xbcd !
0xc4d !
0xc55 - 0xc56 !
0xcbc !
0xccd !
0xd4d !
0xdca !
0xe38 - 0xe3a !
0xe48 - 0xe4b !
0xeb8 - 0xeb9 !
0xec8 - 0xecb !
0xf18 - 0xf19 !
0xf35 !
0xf37 !
0xf39 !
0xf71 - 0xf72 !
0xf74 !
0xf7a - 0xf7d !
0xf80 !
0xf82 - 0xf84 !
0xf86 - 0xf87 !
0xfc6 !
0x1037 !
0x1039 - 0x103a !
0x108d !
0x135d - 0x135f !
0x1714 !
0x1734 !
0x17d2 !
0x17dd !
0x18a9 !
0x1939 - 0x193b !
0x1a17 - 0x1a18 !
0x1a60 !
0x1a75 - 0x1a7c !
0x1a7f
0x1ab0 - 0x1abd !
0x1b34 !
0x1b44 !
0x1b6b - 0x1b73
0x1baa - 0x1bab !
0x1be6 !
0x1bf2 - 0x1bf3 !
0x1c37 !
0x1cd0 - 0x1cd2 !
0x1cd4 - 0x1ce0 !
0x1ce2 - 0x1ce8 !
0x1ced !
0x1cf4 !
0x1cf8 - 0x1cf9 !
0x1dc0 - 0x1df5 !
0x1dfb - 0x1dff !
0x20d0 - 0x20dc !
0x20e1 !
0x20e5 - 0x20f0 !
0x2cef - 0x2cf1
0x2d7f !
0x2de0 - 0x2dff
0x302a - 0x302f !
0x3099 - 0x309a
0xa66f !
0xa674 - 0xa67d !
0xa69e - 0xa69f !
0xa6f0 - 0xa6f1
0xa806 !
0xa8c4 !
0xa8e0 - 0xa8f1
0xa92b - 0xa92d !
0xa953 !
0xa9b3 !
0xa9c0 !
0xaab0 !
0xaab2 - 0xaab4 !
0xaab7 - 0xaab8 !
0xaabe - 0xaabf !
0xaac1 !
0xaaf6 !
0xabed !
0xfb1e !
0xfe20 - 0xfe2f !
0x101fd
0x102e0 !
0x10376 - 0x1037a !
0x10a0d !
0x10a0f !
0x10a38 - 0x10a3a !
0x10a3f !
0x10ae5 - 0x10ae6 !
0x11046 !
0x1107f !
0x110b9 - 0x110ba !
0x11100 - 0x11102 !
0x11133 - 0x11134 !
0x11173 !
0x111c0 !
0x111ca !
0x11235 - 0x11236 !
0x112e9 - 0x112ea !
0x1133c !
0x1134d !
0x11366 - 0x1136c !
0x11370 - 0x11374 !
0x11442 !
0x11446 !
0x114c2 - 0x114c3 !
0x115bf - 0x115c0 !
0x1163f !
0x116b6 - 0x116b7 !
0x1172b !
0x11c3f !
0x16af0 - 0x16af4 !
0x16b30 - 0x16b36 !
0x1bc9e !
0x1d165 - 0x1d169
0x1d16d - 0x1d172
0x1d17b - 0x1d182
0x1d185 - 0x1d18b
0x1d1aa - 0x1d1ad
0x1d242 - 0x1d244
0x1e000 - 0x1e006 !
0x1e008 - 0x1e018 !
0x1e01b - 0x1e021 !
0x1e023 - 0x1e024 !
0x1e026 - 0x1e02a !
0x1e8d0 - 0x1e8d6 !
0x1e944 - 0x1e94a !
这导致总共 814 个代码点。