Java 与字节索引之间的字符索引
我知道如何使用特定编码将字符串转换为字节数组,但如何将字符索引转换为字节索引(在Java中) 例如,在UTF-32中,字符索引Java 与字节索引之间的字符索引,java,unicode,character-encoding,Java,Unicode,Character Encoding,我知道如何使用特定编码将字符串转换为字节数组,但如何将字符索引转换为字节索引(在Java中) 例如,在UTF-32中,字符索引i是字节索引4*i,因为每个UTF-32字符都有4个字节宽。但在UTF-8中,大多数英文字符都是1字节宽,大多数其他脚本中的字符都是2或3字节宽,少数是4字节宽。对于给定的字符串和编码,如何获得每个字符的起始字节索引数组 这里有一个例子来说明我的意思。字符串“Helloمحبا”こんにちは"具有以下索引:[0、1、2、3、4、5、6、8、10、12、14、16、17、20
i
是字节索引4*i
,因为每个UTF-32字符都有4个字节宽。但在UTF-8中,大多数英文字符都是1字节宽,大多数其他脚本中的字符都是2或3字节宽,少数是4字节宽。对于给定的字符串和编码,如何获得每个字符的起始字节索引数组
这里有一个例子来说明我的意思。字符串“Helloمحبا”こんにちは"具有以下索引:[0、1、2、3、4、5、6、8、10、12、14、16、17、20、23、26、29]
,因为拉丁字符各为1字节,阿拉伯字符各为2字节,日语字符各为3字节。(在累积和之前,数组是[1、1、1、1、2、2、2、2、1、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;
}
输出:
[0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 17, 20, 23, 26, 29]
U+FFFF上面的奇异Unicode字符,那些不适合Java的16位字符类型的字符,有点麻烦。例如,圣诞树表情符号U+1F384(你在这里问两个独立的问题——一个关于Python,一个关于Java。最好分开问,这样你就可以“接受”了"每个问题的最佳答案。好的,在这个问题中,我将询问并接受关于Java的答案。注释中的Python信息将是一个受欢迎的奖励。好的,您知道在Java中,所有字符串都存储在UTF-16内部吗?ps:如果必须,那么的描述部分将为您提供将UTF-8解析为Unicode所需的信息e字符…我正在使用一个在字节数组上扩展POSIX正则表达式的库——它没有Java字符串的概念,它返回匹配项作为字节数组的索引。一个选项是str.getBytes(“utf-32be”)
并将它给我的所有索引除以4。我想使用Java的内部编码(utf-16be?)为了提高效率,其中的因素通常是——但并不总是——2.我希望它始终有效。哦+1为了偷偷地进入a,我从中学到了一些东西。一是一些代码点由两个JavaString
索引表示:我认为“Xon补充字符问题的一个解决方案是将循环替换为(int i=0;i
@VGR主要问题不是如何编写循环,而是如何赋予与UTF-16代码单元对应的数组元素有用的含义。例如,”@JimPivarski”看起来Java在这方面只走了一半,“确实如此,但Java不应该受到指责。Unicode联盟已经宣布16位(最多U+FFFF个字符)对每个人来说都应该足够了。Java于1995年问世,其字符串和字符的设计都是围绕16位的限制,这在当时是非常进步的。1996年,Unicode联盟决定,他们实际上想要再容纳100万左右的字符,而在现有的Java API中,没有好的方法来实现这一点。而且是的,许多应用程序不能正确处理它。
[0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 17, 20, 23, 26, 29]