От ISO-8859-1 до UTF-8 в Java (runescape API)

Я пытаюсь создать бота Discord, который получает информацию из Runescape API и возвращает информацию о пользователе. У меня проблема, когда в имени пользователя есть пробел.

API runescape дает файл в ISO-8859-1, и я пытаюсь преобразовать его в UTF-8

2 примера из файла: lil Jimmy и lil jessica. Цикл находит совпадение для Джессики, но не для Джимми.

Код для получения и чтения файла:

    InputStream input = null;
    InputStreamReader inputReader = null;
    BufferedReader reader = null;

        URL url = new URL("http://services.runescape.com/m=clan-hiscores/members_lite.ws?clanName=uh");
        input = url.openConnection().getInputStream();            
        inputReader = new InputStreamReader(input, "ISO-8859-1");
        reader = new BufferedReader(inputReader);
        String line;
        while ((line = reader.readLine()) != null) {                
        String[] parts = line.split(",");
        parts[0] = new String(parts[0].getBytes("UTF-8"), "ISO-8859-1");

            if (parts[0].equals("lil Jimmy")) {System.out.println("lil Jimmy found");}  
            if (parts[0].equals("lil jessica")) {System.out.println("lil jessica found");}

Кто-нибудь знает, что я делаю не так? Заранее благодарим вас за то, что нашли время помочь!

Изменить 1: я добавил «ISO-8859-1» в inputReader, как сказано в ответах. Теперь следующий шаг - заменить пробелы без переноса на обычные пробелы.

Изменить 2: Неразрывные пробелы могут быть решены с помощью:

       parts[0] = parts[0].replaceAll("\u00a0","aaaaaaaaa");
       parts[0] = parts[0].replaceAll("\u00C2","bbbbbbbbb");
       parts[0] = parts[0].replaceAll("bbbbbbbbbaaaaaaaaa", " ");

Aaaaaa заменяет неразрывный пробел на обычный, а aaaaa удаляет римский символ a (Â), который он помещает перед пробелом.

Спасибо всем за помощь!

Если вы измените вопрос, чтобы включить ответы, это сделает ответы очень запутанными, и вопрос концептуально исчезнет, ​​не оставив никакой ценности в будущем.

Tom Blodget 27.03.2018 19:04

При чем здесь UTF-8? Вы считываете текстовый файл - теперь с правильной кодировкой символов - в текстовые типы данных (line), а затем обрабатываете. (Иногда важно знать, что в текстовых типах данных Java используется кодировка UTF-16 [как и в VB4, .NET, JavaScript,…].) Текстовый файл на самом деле не закодирован с помощью ISO-8859-1?

Tom Blodget 27.03.2018 19:08
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
220
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Если вы хотите убедиться, что вы правильно читаете данные, используйте:

inputReader = InputStreamReader(input, "ISO-8859-1");

После этого я не уверен, почему вы пытаетесь преобразовать в UTF-8, поскольку с этого момента вы просто используете текст как String. Сама строка не имеет кодировки. (Ну, в определенном смысле строка Java похожа на UTF-16 по своему внутреннему представлению, но это целая куча червей, о которых вам не нужно беспокоиться здесь.)

Я добавил ваше решение в код и снова попытался найти Джимми. Он выводит «lil Jimmy», но все равно не соответствует в цикле. Для печати я использовал System.out.println (parts [0]);

Michael 26.03.2018 19:22

Вам также понадобится решение, упомянутое кем-то о замене пробелов без упаковки обычными пробелами - я не вникал так глубоко в проблему, чтобы сам найти эту другую проблему.

kshetline 26.03.2018 19:25

Сначала вы не предоставляете кодировку в своем InputStreamReader, что заставляет его использовать кодировку по умолчанию вместо той, которую он должен использовать, а затем вы делаете сумасшедшие вещи, пытаясь исправить это, что вам не нужно делать, и это выиграло не работает должным образом.

Также вы не закрываете открытый поток, вы должны использовать try-with-resources.

Вероятно, это должно выглядеть примерно так:

URL url = new URL("http://services.runescape.com/m=clan-hiscores/members_lite.ws?clanName=uh");         
try(BufferedReader inputReader = new BufferedReader(new InputStreamReader(url.openConnection().getInputStream(), StandardCharsets.ISO_8859_1))) {
    String line;
    while ((line = reader.readLine()) != null) {                
        String[] parts = line.split(",");
        if (parts[0].equals("lil Jimmy")) {System.out.println("lil Jimmy found");}  
        if (parts[0].equals("lil jessica")) {System.out.println("lil jessica found");}
    }
}
Ответ принят как подходящий

Глядя на загруженный текстовый файл: Пробел для «lil jessica» - это обычный пробел (U + 0020), для «lil Jimmy» (и для большинства других) - неразрывный пробел (U + 00A0).

Если вас не волнует нарушение или неразрывность, возможно, самый простой способ - заменить его обычным пробелом в строке ввода. Что-то вроде:

parts[0] = new String(parts[0].getBytes("UTF-8"), "ISO-8859-1");
parts[0] = parts[0].replaceAll("\u00a0"," ");
if (parts[0].equals("lil Jimmy")) {System.out.println("lil Jimmy found");}

Вы были совершенно правы! это был пробел и римская буква А вместе. Спасибо за ваш вклад, вы мне очень помогли!

Michael 26.03.2018 19:59

Другие вопросы по теме