Jim*_*ski 2 java unicode character-encoding
我知道如何使用特定的编码将字符串转换为字节数组,但是如何将字符索引转换为字节索引(在Java中)?
例如,在UTF-32中,字符索引i为字节索引,4 * i因为每个UTF-32字符均为4字节宽。但是在UTF-8中,大多数英文字符为1字节宽,大多数其他脚本中的字符为2或3字节宽,少数为4字节宽。对于给定的字符串和编码,如何获得每个字符的起始字节索引数组?
这是我的意思的例子。"Hello ????? ?????"UTF-8中的字符串具有以下索引:[0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 17, 20, 23, 26, 29]因为拉丁字符每个1个字节,阿拉伯字符每个2个字节,日语字符每个3个字节。(在累积和之前,数组为[1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 3, 3, 3, 3, 3]。)
Java中是否有一个库函数可以计算这些索引位置?它需要高效,所以我不应该仅将每个字符转换为单独的字节数组来查询其长度。是否有一些简单的方法可以根据Unicode的知识自己进行计算?通过识别表示下一个字符宽度的特殊字节,应该可以一次通过。
我认为这可以满足您的要求:
static int[] utf8ByteIndexes(String s) {
int[] byteIndexes = new int[s.length()];
int sum = 0;
for (int i = 0; i < s.length(); i++) {
byteIndexes[i] = sum;
int c = s.codePointAt(i);
if (Character.charCount(c) == 2) {
i++;
byteIndexes[i] = sum;
}
if (c <= 0x7F) sum += 1; else
if (c <= 0x7FF) sum += 2; else
if (c <= 0xFFFF) sum += 3; else
if (c <= 0x1FFFFF) sum += 4; else
throw new Error();
}
return byteIndexes;
}
Run Code Online (Sandbox Code Playgroud)
给定一个Java字符串,它将返回对应char于String中每个字符串的UTF-8字节索引数组。
System.out.println(Arrays.toString(utf8ByteIndexes("Hello ????? ?????")));
Run Code Online (Sandbox Code Playgroud)
输出:
[0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 17, 20, 23, 26, 29]
Run Code Online (Sandbox Code Playgroud)
U + FFFF以上的奇异Unicode字符(不适合Java的16位char类型)有点麻烦。例如,圣诞树表情符号U + 1F384(
)使用两个Java“字符”进行编码。对于这些,上面的函数为两个字符返回相同的字节索引:
System.out.println(Arrays.toString(utf8ByteIndexes("xy")));
Run Code Online (Sandbox Code Playgroud)
输出:
[0, 1, 1, 5]
Run Code Online (Sandbox Code Playgroud)
总的累积字节数是正确的(如果使用UTF-8编码,表情符号将占用4个字节)。
| 归档时间: |
|
| 查看次数: |
1282 次 |
| 最近记录: |