我正在尝试查找子字符串方法或characterAt方法,该方法适用于JAVA中包含UTF-8编码文本的字符串。
在内部,JAVA使用UTF-16。这意味着String由大小为2个字节的字符组成。 UTF-8字符的大小最多为6个字节。当JAVA将其存储在String中时,它会将UTF-8字符分割为多个字符。
例如: 字符U + 20000(UTF-8十六进制:F0 A0 80 80)作为带有两个字符的字符串(UTF-16十六进制:D840和DC00)存储在JAVA内部。
当你有一个包含4字节UTF-8字符的字符串,并使用长度时,答案是“2”。当你使用substring(0,1)时,你会得到角色的前半部分。
一些代码来说明这一点:
ByteBuffer inputBuffer = ByteBuffer.wrap(new byte[]{(byte)0xF0, (byte)0xA0, (byte)0x80, (byte)0x80});
CharBuffer data = Charset.forName("UTF-8").decode(inputBuffer);
String string_test = data.toString();
int length = string_test.length();
String first_half = string_test.substring(0, 1);
String second_half = string_test.substring(1, 2);
String full_character = string_test.substring(0, 2);
所有这些,即使意外,也不是错误,因为JAVA在UTF-16中工作。 固有的UTF-8支持会很好。但它不存在。
JAVA在默认库中是否有任何类,或者某个类是否存在提供UTF-8支持的地方?如:
或者,对此常用的解决方案是什么?在读取UTF-8文件时,将所有非UTF-16支持的UTF-8字符转换为默认的UTF-16字符?因此,丢失了UTF-16不支持的代码点范围内的所有字符信息?这在我的具体实现中不一定是个问题,所以如果有一个共同的方法,我会感兴趣。
答案 0 :(得分:8)
JAVA在默认库中是否有任何类,或者某个类是否存在提供UTF-8支持的类?
你真的不支持UTF-8。你是在Unicode代码点(普通的32位整数)之后,而不是UTF-16代码单元。是的,Java提供了对此的支持,但它并非非常易于使用。
例如,要获取特定代码点,请使用String.codePointAt
- 请注意,您提供的索引是以UTF-16代码单位表示的,不是代码点。< / p>
要在代码点中查找长度,请使用String.codePointCount
。
要查找子字符串,您需要根据UTF-16代码单位查找偏移量,然后使用普通的substring
方法;使用String.offsetByCodePoints
找到正确的索引。
基本上查看包含String
的所有方法的codePoint
API。
答案 1 :(得分:0)
您应该寻找的是Java对UTF-32的原生支持。查看String#*codePoint*
方法,例如codePointAt
。