2010-07-01 2 views
10

У меня возникли проблемы с результатами amazon api.как преобразовать кодировку символов с ruby ​​1.9

служба возвращает строку с юникод символов: Learn Цель \ XE2 \ x80 \ x93C на Mac (Learn Series)

с рубином 1.9.1 строка не может даже были обработаны:

REXML::ParseException: #<Encoding::CompatibilityError: incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string)> 

... 

Exception parsing 

Line: 1 

Position: 1636 

Last 80 unconsumed characters: 

Learn Objective–C on the Mac (Learn Series) 
+2

I настоятельно рекомендую читать * Абсолютный минимум Каждый разработчик программного обеспечения Абсолютно, положительно должен знать об Unicode и наборах символов (без оправданий!) * (http://www.joelonsoftware.com/articles/Unicode.html), даже если вы уже фа miliar с кодировками и т. д. – ewall

+2

Я недавно прочитал статью yehuda katz о кодировании в 1.9 и подумал: WTF ?! (http://yehudakatz.com/2010/05/17/encodings-unabridged/) статья, которую вы связываете, отличная. – phoet

ответ

29

В качестве точек исключения ваша строка кодируется ASCII-8BIT. Вы должны изменить кодировку. Существует long story об этом, но если вы заинтересованы в быстром решении, просто force_encoding на строку, прежде чем сделать какой-либо обработки:

s = "Learn Objective\xE2\x80\x93C on the Mac" 
# => "Learn Objective\xE2\x80\x93C on the Mac" 
s.encoding 
# => #<Encoding:ASCII-8BIT> 
s.force_encoding 'utf-8' 
# => "Learn Objective–C on the Mac" 
+0

- это вопрос ответа, который отправляется с amazon-service? если он установил другой тип контента? – phoet

+0

Я не работал с AWS, поэтому я не знаю, как была загружена эта строка, но вы можете установить кодировку по умолчанию на уровне (Ruby), поэтому есть вероятность, что она решит проблему - подробнее о ссылке в ответ. Кстати, я не думаю, что есть _issue_ вообще, Ruby просто не пытается (и не должен) пытаться угадать, какая кодировка строки, которую он получает, находится. –

+0

Возможно; это означает, что HTTParty должен позаботиться об этом. –

25

решение Младен работает, если все, что закодировано в ASCII-8bit фактически могут быть преобразованы непосредственно к UTF-8. Он прерывается, когда есть символы, которые 1) недействительны, или 2) не определены в UTF-8. Тем не менее, это будет работать (в 1.9.2 и выше:.

new_str = s.encode('utf-8', 'binary', :invalid => :replace, 
    :undef => :replace, :replace => '') 

ASCII-8BIT эффективно двоичный Этот код преобразует кодировку UTF-8, в то время как правильно дело с некорректными и неопределенных символов, которые:. Недопустимый параметр указывает, что недействительные символы будут заменены. Опция: undef указывает, что заменяются неопределенные символы. Опция: replace определяет, что заменить недействительные или неопределенные символы. В этом случае я решил просто удалить их.

+0

э-э, отлично выглядит! попробуем это! – phoet

+0

Вы попробовали механизм ': fallback'? Я попытался заменить некоторые кодировки 'windows-1252', такие как' u00E4' для ä, но это не сработало :( – phoet

+0

Это просто спасло меня для меня при потоковой передаче файла в тело HTTP для публикации ... Большое спасибо! +1 – stuartc

Смежные вопросы