如何将编码从ASCII-8BIT转换为另一个,而不通过ruby中的UTF-8?

时间:2018-01-11 15:31:55

标签: ruby encoding utf-8

irb(main):010:0> str = "sar\xE0".force_encoding "ASCII-8BIT"
irb(main):011:0> str.encode 'ISO-8859-1', "ASCII-8BIT"
Encoding::UndefinedConversionError: "\xE0" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to ISO-8859-1
    from (irb):11:in `encode'
    from (irb):11
    from /Users/ben/.rbenv/versions/2.4.1/bin/irb:11:in `<main>'

我有一个字符串ASCII-8BIT(二进制),我想把它带到另一个编码,但似乎每次转换都试图将它转换为utf-8,因此它失败了(基本上它迫使我替换未定义的字符。)

为什么会这样?我怎么能避免它?

1 个答案:

答案 0 :(得分:1)

给定二进制(ASCII-8BIT)编码的字符串:

str = "sar\xE0".b #=> "sar\xE0"
str.encoding      #=> #<Encoding:ASCII-8BIT>

你可以通过force_encoding告诉Ruby这个字符串实际上在ISO-8859-1中:

str.force_encoding('ISO-8859-1') #=> "sar\xE0"
str.encoding                     #=> #<Encoding:ISO-8859-1>

请注意,您仍然会看到\xE0,因为Ruby不会尝试转换该字符。

在UTF-8终端上打印字符串给出:

puts str
sar�

显示replacement character,,因为0xE0是UTF-8中的无效字节。

在ISO-8859-1终端上打印相同的字符串但是会给出:

puts str
sarà

要在Ruby中使用字符串,通常需要通过encode!将其转换为UTF-8:

str.encode!('UTF-8') #=> "sarà"
str.encoding         #=> #<Encoding:UTF-8>

或者通过将目标编码和源代码编码传递给encode!,只需一步即可:

str = "sar\xE0".b                  #=> "sar\xE0"
str.encode!('UTF-8', 'ISO-8859-1') #=> "sarà"
str.encoding                       #=> #<Encoding:UTF-8>