Bri*_*Hsu 1 java unicode scala character-encoding unicode-string
我正在尝试将包含CJK ExtB计划中的Unicode字符的Java字符串转换为十进制NCR.
例如(你可以试试http://people.w3.org/rishida/tools/conversion/):
游鍚堃𧦧懷这是我尝试过的(在Scala中):
def charToHex(char: Char) = "&#%d;" format(char.toInt)
def stringToHex (string: String) = string.flatMap(charToHex)
println (stringToHex("???")) // 游鍚堃
println (stringToHex("?")) // ��懷
println ("?".toCharArray().length) // Why it is 3?
Run Code Online (Sandbox Code Playgroud)
如您所见,它在第一种情况下正确转换,三个unicode字符转换为三个NCR.
但在第二种情况下"怀",只有两个unicode字符,但Java/Scala似乎认为它是一个包含三个字符的字符串.
那么,这里发生了什么,我怎么能正确地转换第二个案例就像我提到的网站上的转换器一样?非常感谢.
更新:
char[] = ?, char.toInt = 55390char[] = ?, char.toInt = 56743char[] = ?, char.toInt = 25079现在我想我知道发生了什么.字符""在UTF-16中编码为0xD85E 0xDDA7,它是4个字节而不是2个字节.因此在转换为char数组时需要2个元素,其中数据类型char只能表示2个字节.
Java(以及Scala)对其字符串使用UTF-16编码,这意味着所有超过2 ^ 16-1的unicode代码点必须用两个字符表示.(实际上,编码方案比这复杂一点.)无论如何,这length是一种在较低级别操作的方法 - 字符 - 因此它返回字符数.
如果你想找出代码点的数量,当你说"两个unicode字符"(例如两个打印出来的符号)时,你可能会直觉地想到这个,你需要使用s.codePointCount(0,s.length).如果你想将它们转换为十六进制,你需要使用代码点而不是Chars,因为并非所有代码点都适合.我对这个问题的回答包含将字符串转换为代码点的Scala代码.(不是效率最高;如果你在大字符串上进行重载文本处理,你想要重写它以使用数组/ ArrayBuffer.)
| 归档时间: |
|
| 查看次数: |
2641 次 |
| 最近记录: |