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
,因此它失败了(基本上它迫使我替换未定义的字符。)
为什么会这样?我怎么能避免它?
答案 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>