когда мы импортируем данные csv, как устранить " недопустимую последовательность байтов в UTF-8"
мы разрешаем пользователям импортировать данные через csv (используя ruby 1.9.2, следовательно, это fastercsv).
будучи пользовательскими данными, конечно, он не может быть должным образом дезинфицирован.
когда мы пытаемся отобразить данные в методе / index, мы иногда получаем ошибку "недопустимая последовательность байтов в UTF-8", указывающую на наш erb, где мы показываем одно из полей widget.name
когда мы делаем импорт, мы хотели бы заставить входящие данные быть действительными... есть ли оператор ruby, который будет отображать строка для допустимой строки utf8, например, что-то вроде
goodstring = badstring.no_more_invalid_bytes
одним из примеров "плохих" данных является символ, который выглядит как дефис, но не является обычным дефисом ascii. Мы предпочли бы сопоставить символы, отличные от utf-8, с разумным эквивалентом ascii (umlat-u собирается u для exmaple), но мы в порядке с простым удалением символа.
так как это при импорте большого количества данных, он должен быть быстрым встроенным оператором, надеюсь...
Примечание: вот пример данных. Файл поставляется в виде windows и 8bit ascii. когда мы импортируем его и в нашем erb мы показываем widget.name. inspect (вместо widget.name) мы получаем:
"Цепи x96 аксессуары"
--- когда мы изменили наш анализ csv, чтобы назначить fldval = d. encode ('UTF-8')
он выдает эту ошибку:
Encoding::UndefinedConversionError in StoresController#importfinderitems
"x96" from ASCII-8BIT to UTF-8
то, что мы ищем, - это простой способ просто заставить его быть действительным utf8 независимо от тип происхождения, даже если мы просто лишаем не-ascii.
хотя это не так "приятно", как принудительное кодирование, это работает с небольшими затратами на наше время импорта:
d.to_s.strip. gsub(/P{ASCII}/, ")
Спасибо, Младен!
8 ответов:
Руби 1.9 КШМ имеет новый парсер, который работает с m17n. Парсер работает с кодировкой ИО объект в строку. Следующие методы:
::foreach, ::open, ::read, and ::readlinesможет принимать дополнительные опции:encodingкоторый вы могли бы указать кодировку.например:
CSV.read('/path/to/file', :encoding => 'windows-1251:utf-8')преобразует все строки в UTF-8.
также вы можете использовать более стандартное имя кодировки 'ISO-8859-1'
CSV.read('/..', {:headers => true, :col_sep => ';', :encoding => 'ISO-8859-1'})
Я ответил на аналогичный вопрос, который касается чтения внешних файлов в 1.9.2 с кодировками, отличными от UTF-8. Я думаю, что ответ вам очень поможет:проблема кодировки символов в Rails v3 / Ruby 1.9.2
обратите внимание, что вам нужно знать исходную кодировку для вас, чтобы конвертировать ее надежно. Есть библиотеки, подобные той, с которой я связался в своем другом ответе, которые могут помочь вам определить это.
кроме того, если вы не загружать данные из файла, вы можете конвертировать кодировку строки в 1.9.2 довольно легко:
'string'.encode('UTF-8')однако редко бывает, что вы создаете строку в другой кодировке, и лучше всего конвертировать ее во время чтения в вашей среде, если это возможно.
Ruby 1.9 может изменить кодировку строки с недопустимым обнаружением и заменой:
str = str.encode('UTF-8', :invalid => :replace)ДЛЯ НЕОБЫЧНЫХ строк, таких как строки, загруженные из файла неизвестной кодировки, разумно использовать #encode вместо регулярного выражения, #gsub или #delete, потому что все они нуждаются в разборе строки-но если строка сломана, она не может быть проанализирована, поэтому эти методы терпят неудачу.
Если вы получите такое сообщение:
error ** from ASCII-8BIT to UTF-8тогда вы, вероятно, пытаетесь преобразовать двоичный файл строка, которая уже находится в UTF-8, и вы можете заставить UTF-8:
str.force_encoding('UTF-8')Если вы знаете, что исходная строка не находится в двоичном формате UTF-8, или если выходная строка имеет символы illiegal, то прочитайте о транслитерациях кодировки Ruby.
Если вы используете рейлинги, вы можете попробовать исправить это следующим
'Your string with strange stuff #@~'.mb_chars.tidy_bytesОн удаляет недопустимые символы utf-8 и заменяет их допустимыми. Дополнительная информация: https://apidock.com/rails/String/mb_chars
загрузите файл CSV в электронную таблицу Google Docs и повторно загрузите его в виде файла CSV. Импорт и вуаля! (Работал в моем случае)
предположительно Google преобразует его в нужный формат..
источник: Excel в CSV с кодировкой UTF-8
Как уже упоминалось кем-то другим, скраб хорошо работает, чтобы очистить это в Ruby 2.1+. Если у вас есть большой файл, вы не можете прочитать все это в памяти, поэтому вы можете использовать скраб следующим образом:
data = IO::read(file_path).scrub("") CSV.parse(data, :col_sep => ',', :headers => true) do |row| puts row end
Comments