我在用Java 10中的Unicode字符苦苦挣扎。
我正在使用java.text.BreakIterator包。
对于此输出:
myString="ab" hex=0061d835dcde0062
myString.length()=4
myString.codePointCount(0,s.length())=3
BreakIterator output:
a hex=0061
hex=d835dcde
b hex=0062
似乎正确。
使用相同的Java代码,然后输出以下 :
myString="G̲íl" hex=0047033200ed006c
myString.length()=4
myString.codePointCount(0,s.length())=4
BreakIterator output:
G̲ hex=00470332
í hex=00ed
l hex=006c
似乎也正确,除了codePointCount = 4。
为什么不是3,并且有一种获取方法
不使用BreakIterator的3值?
我的目标是确定字符串的所有(输出)字符是否都是 16位,还是存在替代字符或组合字符?
答案 0 :(得分:5)
“ G̲íl” 是四个代码点:U + 0047,U + 0332,U + 00ED,U + 006C。
U + 0332是一个组合字符,但是一个单独的代码点。这与您的第一个示例不同,后者需要使用一个代理对(2个UTF-16代码单元)来表示U + 1D4DE-但后者仍然是单个代码 point 。
BreakIterator
在文本中找到边界-此处组合的两个代码点在这种意义上没有边界。从文档中:
字符边界分析使用户可以按照他们期望的方式与字符进行交互,例如,当光标在文本字符串中移动时。字符边界分析提供了正确的字符串浏览方式,而与字符的存储方式无关。
所以我认为这里一切正常。
答案 1 :(得分:1)
一个代码点对应一个Unicode字符。
Java以UTF-16(即16位单元)表示Unicode。与第一个示例一样,代码点值大于U + FFFF的字符由一对“代理字符”表示。因此第3个结果。
在第二种情况下,您有一个示例,该示例不是单个Unicode字符。它是一个字符,字母G,其后是另一个字符COMBINING CHARACTER LOW LINE。每个定义有两个代码点。因此是4的第二个结果。
通常,Unicode具有字符属性表(我不确定此处是否有正确的词),并且有可能发现您的代码点之一是组合字符。
看一下Character类。 getType(character)会告诉您代码点是组合字符还是替代字符。