gpt4 book ai didi

java - 字符索引到和来自字节索引

转载 作者:行者123 更新时间:2023-12-01 14:09:35 25 4
gpt4 key购买 nike

我知道如何使用特定编码将字符串转换为字节数组,但是如何将字符索引转换为字节索引(在 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;
}

给定一个 Java 字符串,它返回与每个 char 对应的 UTF-8 字节索引的数组。在字符串中。
System.out.println(Arrays.toString(utf8ByteIndexes("Hello مرحبا こんにちは")));

输出:
[0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 17, 20, 23, 26, 29]

U+FFFF 之上的异国 Unicode 字符,那些不适合 Java 的 16 位字符类型的字符,有点麻烦。例如,圣诞树表情符号 U+1F384 ( 🎄 ) 使用两个 Java“字符”进行编码。对于那些,上面的函数为两个字符返回相同的字节索引:
System.out.println(Arrays.toString(utf8ByteIndexes("x🎄y")));

输出:
[0, 1, 1, 5]

虽然总的累积字节数是正确的(如果用 UTF-8 编码,表情符号需要 4 个字节)。

关于java - 字符索引到和来自字节索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27651543/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com