【问题标题】:How to convert array of UCS-2 bytes to UTF-8 string in Ruby?如何在 Ruby 中将 UCS-2 字节数组转换为 UTF-8 字符串?
【发布时间】:2014-09-14 10:14:24
【问题描述】:

我在 Ruby 中有一个 UCS-2LE 编码字节数组,由于这是我对 Ruby 的完整开始,我正在努力将其转换为 UTF-8 字符串,我在 PHP 和 Java 中使用相同的代码工作得很好。

在 PHP 中我使用的是 iconv 库,但在 Ruby 中 iconv 已被弃用:

$str = iconv('UCS-2LE', 'UTF-8//IGNORE', implode($byte_array));

在 Java 中我正在使用:

str = new String(byte_array, "UTF-16LE");

数组中的字节编码为每1个字符2个字节,如何在Ruby中进行类似的转换?我尝试了一些解决方案,但它对我不起作用。谢谢。

【问题讨论】:

  • byte_array.pack("C*").force_encoding("UTF-16LE").encode("UTF-8") 应该可以工作
  • @Stefan 它工作得很好,我构建了将项目作为 .chr 类型的数组,我删除了 .chr 并添加了你的代码,它工作得很好,我不明白的一件事,当文档指出 C 是一个字符(而不是宽字符)时,它如何与 C* 类型一起工作?
  • C 将整数值解释为 1 字节字符,即 [65].pack("C")65 (0x41) 转换为 "A" ("\x41")。结果是一个带有 ASCII-8BIT 编码的字符串。 force_encoding 然后重新解释字节。
  • 好的,我明白了,谢谢 :)

标签: ruby unicode utf-8 string-conversion ucs2


【解决方案1】:

假设一个字节数组:

byte_array = [70, 0, 111, 0, 111, 0]

您可以使用Array#pack 将整数值转换为字符(C 将每个整数视为无符号字符):

string = byte_array.pack("C*")       #=> "F\x00o\x00o\x00"

pack 返回一个 ASCII-8BIT 编码的字符串:

string.encoding                      #=> #<Encoding:ASCII-8BIT>

您现在可以使用 String#force_encoding 将字节重新解释为 UTF-16 字符串:

string.force_encoding("UTF-16LE")    #=> "Foo"

到目前为止字节没有改变:

string.bytes                         #=> [70, 0, 111, 0, 111, 0]

要将字符串转码为另一种编码,请使用String#encode

utf8_string = string.encode("UTF-8") #=> "Foo"
utf8_string.bytes                    #=> [70, 111, 111]

整个转换可以写在一行中:

byte_array.pack("C*").force_encoding("UTF-16LE").encode("UTF-8")

或者通过将源编码作为第二个参数传递给encode

byte_array.pack("C*").encode("UTF-8", "UTF-16LE")

【讨论】:

    猜你喜欢
    • 2010-10-29
    • 2016-08-14
    • 2011-05-24
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    相关资源
    最近更新 更多