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
所以它失败了(基本上它迫使我替换未定义的字符)。
为什么会发生这种情况?我怎样才能避免它?
最佳答案
给定一个二进制 (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>
关于ruby - 如何将编码从 ASCII-8BIT 转换为另一种编码,而不通过 ruby 中的 UTF-8?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48210640/