Java конвертировать кодировку

У меня есть строка, которая раньше была тегом xml, где содержатся mojibakes:
<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"));

но у меня всегда были другие моджибейки или знаки вопроса вместо персонажей.

В: Как я могу сделать то же самое, что и 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: 킜킾톁킺킲킰

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)

Вы были довольно близко Тем не мение, getBytes используется для кодирования UTF-8, а не для декодирования. То, что вы хотите, это что-то вроде

String string = "Ð\x9cоÑ\x81ква";
byte[] bytes = string.getBytes("UTF-8");
System.out.println(new String(bytes, "UTF-8"));
Другие вопросы по тегам