Ruby 1.8.7 не отличался многобайтовыми символами, как 1.9+. В общем случае он обрабатывает строку как набор байтов, а не символов. Если вам нужна лучшая обработка таких символов, подумайте об обновлении до версии 1.9+.
У Джеймса Грея есть серия статей о работе с многобайтовыми символами в Ruby 1.8. Я настоятельно рекомендую потратить время на их прочтение. Это сложная тема, так что вы захотите прочитать всю серию, которую он написал пару раз.
Кроме того, для поддержки кодировки 1.8 требуется установленный флаг $KCODE
:
$KCODE = "U"
поэтому вам нужно добавить это в код, работающий в 1.8.
Вот небольшой пример кода:
#encoding: UTF-8
require 'rubygems'
require 'iconv'
chars = "éáéíóúÀÉÍÓÚ"
puts Iconv.iconv("ASCII//translit", "utf-8", chars)
puts chars.split('')
puts chars.split('').join
Используя ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-darwin10.7.0] и запуская его в IRB, я получаю:
1.8.7 :001 > #encoding: UTF-8
1.8.7 :002 >
1.8.7 :003 > require 'iconv'
true
1.8.7 :004 >
1.8.7 :005 > chars = "\303\251\303\241\303\251\303\255\303\263\303\272\303\200\303\211\303\215\303\223\303\232"
"\303\251\303\241\303\251\303\255\303\263\303\272\303\200\303\211\303\215\303\223\303\232"
1.8.7 :006 >
1.8.7 :007 > puts Iconv.iconv("ASCII//translit", "utf-8", chars)
'e'a'e'i'o'u`A'E'I'O'U
nil
1.8.7 :008 >
1.8.7 :009 > puts chars.split('')
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
nil
1.8.7 :010 > puts chars.split('').join
éáéíóúÀÉÍÓÚ
В строке 9 вывода я сказал Ruby разделить строку на символы, которые в версии 1.8.7 представляли собой байты. Результирующий '?' означает, что он не знал, что делать с выводом. Строку 10 я приказал разбить, в результате чего получился массив байтов, который join
затем пересобрал в обычную строку, что позволило нормально перевести многобайтовые символы.
Запуск того же кода с использованием Ruby 1.9.2 показывает лучшее, более ожидаемое и желательное поведение:
1.9.2p290 :001 > #encoding: UTF-8
1.9.2p290 :002 >
1.9.2p290 :003 > require 'iconv'
true
1.9.2p290 :004 >
1.9.2p290 :005 > chars = "éáéíóúÀÉÍÓÚ"
"éáéíóúÀÉÍÓÚ"
1.9.2p290 :006 >
1.9.2p290 :007 > puts Iconv.iconv("ASCII//translit", "utf-8", chars)
'e'a'e'i'o'u`A'E'I'O'U
nil
1.9.2p290 :008 >
1.9.2p290 :009 > puts chars.split('')
é
á
é
í
ó
ú
À
É
Í
Ó
Ú
nil
1.9.2p290 :010 > puts chars.split('').join
éáéíóúÀÉÍÓÚ
Ruby поддерживал многобайтность символов через расширение split('')
.
Обратите внимание, что в обоих случаях Iconv.iconv
поступил правильно, создав символы, визуально похожие на введенные символы. Хотя начальный апостроф выглядит неуместно, он служит напоминанием о том, что изначально символы были подчеркнуты.
Для получения дополнительной информации см. ссылки справа на связанные вопросы или попробуйте этот поиск SO для [ruby] [iconv]
person
the Tin Man
schedule
09.12.2011