如何在=D0=93=D0=B0=D0=B7=D0=B5=D1=82=D0=B0
中转换像Java
这样的UTF-8值?
我尝试过类似的事情:
Character.toCodePoint((char)(Integer.parseInt("D0", 16)),(char)(Integer.parseInt("93", 16));
但它不会转换为有效的代码点。
答案 0 :(得分:4)
该字符串是十六进制的字节编码,因此最好的方法是将字符串解码为byte[]
,然后调用new String(bytes, StandardCharsets.UTF_8)
。
<强>更新强>
这是一个稍微更直接的解码字符串版本,而不是另一个答案中的“sstan”。当然两个版本都很好,所以使用哪个让你感觉更舒服,或者编写自己的版本。
String src = "=D0=93=D0=B0=D0=B7=D0=B5=D1=82=D0=B0";
assert src.length() % 3 == 0;
byte[] bytes = new byte[src.length() / 3];
for (int i = 0, j = 0; i < bytes.length; i++, j+=3) {
assert src.charAt(j) == '=';
bytes[i] = (byte)(Character.digit(src.charAt(j + 1), 16) << 4 |
Character.digit(src.charAt(j + 2), 16));
}
String str = new String(bytes, StandardCharsets.UTF_8);
System.out.println(str);
输出
Газета
答案 1 :(得分:1)
在UTF-8中,单个字符并不总是使用相同的字节数进行编码。根据字符的不同,可能需要1,2,3或甚至4个字节进行编码。因此,尝试将UTF-8字节本身映射到使用UTF-16编码的Java char
绝对不是一件小事,其中每个char
使用2个字节进行编码。更不用说,根据角色(代码点&gt; 0xffff),您可能还需要担心处理代理字符,这只是一个容易出错的复杂问题。
所有这些都说Andreas
绝对正确。您应该专注于将字符串解析为字节数组,然后让内置库将UTF-8字节转换为Java字符串。从Java String中,如果你想要的话,提取Unicode代码点是微不足道的。
以下是一些示例代码,显示了可以实现的一种方法:
public static void main(String[] args) throws Exception {
String src = "=D0=93=D0=B0=D0=B7=D0=B5=D1=82=D0=B0";
// Parse string into hex string tokens.
String[] tokens = Arrays.stream(src.split("="))
.filter(s -> s.length() != 0)
.toArray(String[]::new);
// Convert the hex string representations to a byte array.
byte[] utf8bytes = new byte[tokens.length];
for (int i = 0; i < utf8bytes.length; i++) {
utf8bytes[i] = (byte) Integer.parseInt(tokens[i], 16);
}
// Convert UTF-8 bytes to Java String.
String str = new String(utf8bytes, StandardCharsets.UTF_8);
// Display string + individual unicode code points.
System.out.println(str);
str.codePoints().forEach(System.out::println);
}
输出:
Газета
1043
1072
1079
1077
1090
1072