Кодирование:: UndefinedConversionError

Я продолжаю получать Encoding::UndefinedConversionError - "\xC2" from ASCII-8BIT to UTF-8 каждый раз, когда пытаюсь преобразовать хэш в строку JSON. Я пробовал с [.encode | .force_encoding](["UTF-8" | "ASCII-8BIT" ]), связывал .encode с .force_encoding, назад, переключая параметры, но ничего не работало, поэтому я поймал такую ​​ошибку:

begin
  menu.to_json
rescue Encoding::UndefinedConversionError
  puts $!.error_char.dump
  p $!.error_char.encoding
end

Где меню представляет собой продолжение dataset.to_hash с содержимым из базы данных MySQL, кодировка utf8_general_ci и возвращает это:

\xC2

‹#Кодировка:ASCII-8BIT›

Кодировка никогда не меняется, какие бы .encode/.force_encoding я ни использовал. Я даже пытался заменить строку .gsub!(/\\\xC2/) безуспешно.

Любые идеи?


person martriay    schedule 21.10.2012    source источник
comment
1. Вы пробовали это? menu.force_encoding("ISO-8859-1").encode("UTF-8") 2. добавьте строку кодировки 'utf-8'` вверху всех ваших файлов .rb. 3. Проверьте настройки среды. что говорит $ echo LC_CTYPE в вашем терминале?   -  person Kashyap    schedule 22.10.2012
comment
Шаг 1 завершился с ошибкой? Шаг 2 сработал? Для шага 3 thegreyblog.blogspot.in/2012/02/ по этой ссылке есть настройки env, с которыми ваша программа должна работать, если вы хотите избежать этой проблемы.   -  person Kashyap    schedule 29.10.2012


Ответы (5)


menu.to_s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')

Это сработало отлично, мне пришлось заменить некоторые лишние символы, но ошибок больше нет.

person martriay    schedule 03.01.2013
comment
Фантастическое решение - решил мою проблему со странными типами в SQL Server. Спасибо! - person Marc Clifton; 27.10.2013
comment
Спасибо! Это работает и для меня, официальный документ ruby ​​для дальнейшего использования здесь - person jmoreira; 16.06.2014

Что вы ожидаете от "\xC2"? Вероятно, Â

С ASCII-8BIT у вас есть двоичные данные, и ruby ​​не может решить, что должно быть.

Вы должны сначала установить кодировку с помощью force_encoding.

Вы можете попробовать следующий код:

Encoding.list.each{|enc|
  begin
    print "%-10s\t" % [enc]
    print "\t\xC2".force_encoding(enc)
    print "\t\xC2".force_encoding(enc).encode('utf-8')
  rescue => err
    print "\t#{err}"
  end
  print "\n"
}

Результатом являются возможные значения в разных кодировках для вашего "\xC2".

Результат может зависеть от вашего формата вывода, но я думаю, вы можете догадаться, какая у вас кодировка.

Когда вы определили нужную вам кодировку (вероятно, cp1251), вы можете

menu.force_encoding('cp1252').to_json

См. также комментарий Кашьяпа.

person knut    schedule 22.10.2012
comment
вот что я сделал: «Encoding.list.each{|enc| begin print %-10s\t % [enc] print menu.to_json.force_encoding(enc) print menu.to_json.force_encoding(enc).encode('utf-8') repair =› err print \t#{err} end напечатайте \n }´ и это то, что я получил для каждого результата: «SJIS-KDDI \xC2 из ASCII-8BIT в UTF-8» - person martriay; 29.10.2012
comment
Этот цикл обнаружения для всех кодировок просто великолепен. Помогли мне решить мой собственный вариант этой задачи. Спасибо! - person pdobb; 14.12.2018

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

str.force_encoding("ASCII-8BIT").encode('UTF-8', undef: :replace, replace: '')
person Ponny    schedule 30.12.2012
comment
Не сработало :( Encoding::UndefinedConversionError в /menu\xC2 из ASCII-8BIT в UTF-8 - person martriay; 03.01.2013
comment
menu.to_s.encode('UTF-8', {:invalid =› :replace, :undef =› :replace, :replace =› '?'}) -› это сработало! :D - person martriay; 03.01.2013

Ваше автоматически принятое решение не работает, фактически ошибок нет, но это НЕ JSON.

Я решил проблему с помощью oj gem, теперь он работает. Это также быстрее, чем стандартная библиотека JSON.

Написание:

   menu_json = Oj.dump menu

Чтение:

   menu2 = Oj.load menu_json

https://github.com/ohler55/oj для получения более подробной информации. Надеюсь, это поможет.

person gvo    schedule 20.09.2013
comment
Проблема была в ошибке, а не в части JSON. Поэтому мои автоматически принятые ответы работают. В любом случае, я проголосую за альтернативное решение. - person martriay; 22.09.2013
comment
Ну я с вами согласен, ошибок уже нет, но это не json строка. Я не знаю, какова была ваша цель, но мне нужно было загрузить обратно мой json, и я хотел действительную строку JSON. Или, может быть, я что-то упустил в предложенном вами решении? - person gvo; 24.09.2013
comment
Этот вопрос был только об ошибке, я не говорю, что мой ответ - лучший выбор, очевидно, что он не для вашей цели, но решает представленную проблему: ошибку кодирования. JSON, о котором я упоминаю в своем вопросе, предназначен для целей контекстуализации. - person martriay; 25.09.2013
comment
Спасибо @gvo! Надеюсь, другие поиски этой ошибки найдут это решение... - person Cyberwiz; 07.12.2017

Параметр :fallback может быть полезен, если вы знаете, какие символы хотите заменить.

"Text ????".encode("ASCII", "UTF-8", fallback: {"????" => ":)"})
#=> hello :)

Из документов:

Устанавливает строку замены данным объектом для неопределенного символа. Объект должен быть хешем, процедурой, методом или объектом, который имеет метод []. Его ключ представляет собой неопределенный символ, закодированный в исходной кодировке текущего транскодера. Его значение может быть любой кодировкой, пока оно не может быть преобразовано в целевую кодировку транскодера.

person user3430535    schedule 29.01.2020