1

我有一个字符串,它曾经是一个包含 mojibakes 的 xml 标签:
<Applicant_Place_Born>Ð&#156;оÑ&#129;ква</Applicant_Place_Born>

我知道完全相同但编码正确的字符串是:
<Applicant_Place_Born>Москва</Applicant_Place_Born>

我知道这一点是因为使用 Tcl 实用程序我可以将其转换为正确的字符串:

# The original string
set s "Ð&#156;оÑ&#129;ква"
# substituting the html escapes
set t "Ð\x9cоÑ\x81ква"
# decode from utf-8 into Unicode
encoding convertfrom utf-8 "Ð\x9cоÑ\x81ква"
Москва

我尝试了不同的变体:

System.out.println(new String(original.getBytes("UTF-8"), "CP1251"));

但我总是得到其他mojibakes或问号而不是字符。

问:我怎样才能像 Tcl 一样做但使用 Java 代码?

编辑:

我尝试过@Joop Eggen 的方法:

import org.apache.commons.lang3.StringEscapeUtils;


public class s {
    static String s;
    public static void main(String[] args) {
        try {
            System.setProperty("file.encoding", "CP1251");
            System.out.println("JVM encoding: " + System.getProperty("file.encoding"));
            s = "Ð&#156;оÑ&#129;ква";
            System.out.println("Original text: " + s);

            s = StringEscapeUtils.unescapeHtml4(s);
            byte[] b = s.getBytes(StandardCharsets.ISO_8859_1);
            s = new String(b, "UTF-16BE");

            System.out.println("Result: " + s);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

转换后的字符串是中文的:

JVM encoding: CP1251 Original text: Ð&#156;оÑ&#129;ква Result: 킜킾톁킺킲킰

4

2 回答 2

2

Java 中的字符串应该始终是正确的 Unicode。在您的情况下,您似乎将 UTF16BE 解释为一些单字节编码。

补丁将是

String string = new StringEscapeUtils().UnescapeHTML4(s);
byte[] b = string.getBytes(StandardCharsets.ISO_8859_1);
string = new String(b, "UTF-16BE");

现在s应该是正确的 Unicode 字符串。

System.out.println(s);

例如,如果操作系统在 Cp1251 中,则应正确转换西里尔文文本。

  • 我猜 s 中的字符实际上是 UTF-16BE 的字节
  • 通过以单字节编码获取字符串的字节,希望不会发生转换
  • 然后将字节字符串设为 UTF-16BE,在内部转换为 Unicode(实际上也是 UTF-16BE)
于 2015-07-02T13:55:34.640 回答
1

你非常接近。但是,getBytes用于编码UTF-8 而不是解码。你想要的是类似的东西

String string = "Ð\x9cоÑ\x81ква";
byte[] bytes = string.getBytes("UTF-8");
System.out.println(new String(bytes, "UTF-8"));
于 2015-07-02T13:55:25.443 回答