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




Если вы хотите убедиться, что вы правильно читаете данные, используйте:
inputReader = InputStreamReader(input, "ISO-8859-1");
После этого я не уверен, почему вы пытаетесь преобразовать в UTF-8, поскольку с этого момента вы просто используете текст как String. Сама строка не имеет кодировки. (Ну, в определенном смысле строка Java похожа на UTF-16 по своему внутреннему представлению, но это целая куча червей, о которых вам не нужно беспокоиться здесь.)
Я добавил ваше решение в код и снова попытался найти Джимми. Он выводит «lil Jimmy», но все равно не соответствует в цикле. Для печати я использовал System.out.println (parts [0]);
Вам также понадобится решение, упомянутое кем-то о замене пробелов без упаковки обычными пробелами - я не вникал так глубоко в проблему, чтобы сам найти эту другую проблему.
Сначала вы не предоставляете кодировку в своем 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");}
Вы были совершенно правы! это был пробел и римская буква А вместе. Спасибо за ваш вклад, вы мне очень помогли!
Если вы измените вопрос, чтобы включить ответы, это сделает ответы очень запутанными, и вопрос концептуально исчезнет, не оставив никакой ценности в будущем.