Как преобразовать символ UTF-8 в ISO Latin 1? - PullRequest
5 голосов
/ 11 марта 2009

Мне нужно преобразовать знак товарного знака UTF-8 в ISO Latin 1 и сохранить его в базе данных, которая также закодирована в ISO Latin 1.

Как я могу сделать это в Java?

Я пробовал что-то вроде

String s2 = new String(s1.getBytes("ISO-8859-1"), "utf-8");

но, похоже, не работает, как я ожидал.

Ответы [ 4 ]

5 голосов
/ 11 марта 2009

Строка в Java всегда находится в Юникоде (UTF-16, эффективно). Преобразования необходимы только тогда, когда вы пытаетесь перейти от текста к двоичной кодировке или наоборот.

Какой персонаж задействован? Вы уверены, что он присутствует даже в ISO Latin 1? Если это так, я ожидаю, что этот символ будет храниться в вашей базе данных без каких-либо проблем. Нет такой вещи как «знак торговой марки UTF-8». Вы можете иметь «байты, представляющие знак торговой марки в кодировке UTF-8», но это будет байтовый массив, а не строка.

РЕДАКТИРОВАТЬ: Если вы имеете в виду символ Unicode U + 2122, то это вне диапазона ISO-Latin-1. Существует зарегистрированный товарный знак U + 00AE, который не то же самое (либо по внешнему виду, либо в юридическом смысле, IIRC), но может быть лучше, чем ничего - если вы хотите использовать это, то просто используйте:

string replaced = original.replace('\u2122', '\u00ae');
4 голосов
/ 20 февраля 2014

Насколько я понимаю, вы пытаетесь сохранить символы (из s1), которые содержат символы, отличные от Latin-1, в БД, которая поддерживает только ISO-8859-1.

  • Во-первых, я согласен с другими, чтобы сказать, что это грязная идея.
    Обратите внимание, что CP1252 близок к ISO-8859-1 (1 байт на символ) и включает в себя

  • Теперь, чтобы ответить на ваш вопрос, я думаю, что вы сделали обратное ..
    Вы хотите закодировать байты UTF-8 в ISO-8859-1:

    String s2 = new String(s1.getBytes("UTF-8"), "ISO-8859-1");
    

    Таким образом, s2 является символьной строкой, которая после кодирования в ISO-8859-1 возвращает массив байтов, который может выглядеть как действительные байты UTF-8.

    Чтобы получить исходную строку, вы должны сделать

    String s1 = new String(s2.getBytes("ISO-8859-1"),"UTF-8");
    

НО ЖДУ! Делая это, вы надеетесь , что любой байт может быть декодирован с помощью ISO-8859-1 .. и что ваша БД примет такие данные. и т.д ..

На самом деле, это действительно неуверенно, потому что официально, ISO-8859-1 не имеет символов для любых байтов . Например, от 80 до 9F.

Тогда

byte[] b = { -97, -100, -128 };
System.out.println( new String(b,"ISO-8859-1") );

будет отображаться ???

Однако в Java , s.getBytes("ISO-8859-1") действительно восстанавливает исходный массив.

2 голосов
/ 11 марта 2009
  1. Прочитайте, что сказал вам Джон Скит. Код, который вы опубликовали, является мусором (он принимает код вашей строки в кодировке UTF-8 и интерпретирует его так, как если бы это был ISO-8859-1, это ничего не дает).
  2. Кодировка ISO-8859-1 (a.k.a Latin1) не содержит символ торговой марки "™".
0 голосов
/ 22 февраля 2012

У меня была похожая проблема, и я решил ее, преобразовав непереводимые символы в сущности. Если вы отобразите информацию позже в виде html, все в порядке.

Если нет, вы можете попытаться преобразовать их обратно в Unicode.

пример на python с «Товарным знаком»:

s = u'yellow bananas\u2122'.encode('latin1', 'xmlcharrefreplace')
# s is 'yellow bananas™'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...