У меня в коде Ruby есть строка UTF-8.Из-за ограничений я хочу преобразовать символы UTF-8 в этой строке в их экранированные эквиваленты (например, \u23
) или просто преобразовать всю строку в UCS-2.Мне нужно явно сделать это, чтобы экспортировать данные в файл
Я попытался сделать следующее в IRB:
my_string = '7.0mΩ'
my_string.encoding
my_string.encode!(Encode::UCS_2BE)
my_string.encoding
Вывод этого:
=> "7.0mΩ"
=> #<Encoding::UTF-8>
=> "7.0m\u2126"
=> #<Encoding::UTF-16BE>
Это, казалось, работало нормально (я получил "ом" как 2126), пока я не читал данные из массива (в Rails):
data.each_with_index do |entry, idx|
puts "#{idx} !! #{entry['title']} !! #{entry['value']} !! #{entry['value'].encode!(Encoding::UCS_2BE)}"
end
Это приводит к ошибке:
несовместимые кодировки символов: UTF-8 и UTF-16BE
Затем я попытался написать простую процедуру преобразования файлов:
File.open(target, 'w', encoding: Encoding::UCS_2BE) do |file|
File.open(source, 'r', encoding: Encoding::UTF_8).each_line do |line|
output.puts(line)
end
end
Это привело ко всем видамстранные символы в файле.
Не уверен, что происходит не так.
Есть ли лучший способ решить эту проблему преобразования данных UTF-8 в UCS-2 в Ruby?Я действительно не возражаю против того, чтобы на самом деле это было изменено в строке на \u2126
как на буквальную часть строки, а не на фактическое значение.
Help!
Временное решение
Я исправил это, чтобы сделать то, что я хочу.Это не очень элегантно, но оно выполняет свою работу (и да, я знаю, что это не красиво ... это просто хак, чтобы получить то, что мне нужно):
def hacky_encode
encoded = self
unless encoded.ascii_only?
encoded = scan(/./).map do |char|
char.ascii_only? ? char : char.unpack('U*').map { |i| '\\u' + i.to_s(16).rjust(4, '0') }
end.join
end
encoed
end
Что можно использовать:
"7.0mΩ".hacky_encode