Java将unicode代码指向字符串

时间:2015-08-30 22:37:47

标签: java unicode utf-8

如何在=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));

但它不会转换为有效的代码点。

2 个答案:

答案 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