【问题标题】:How to convert encoding from ASCII-8BIT to another, without passing through UTF-8 in ruby?如何在 ruby​​ 中不通过 UTF-8 将编码从 ASCII-8BIT 转换为另一种?
【发布时间】:2018-01-11 15:31:54
【问题描述】:
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,所以它失败了(基本上它迫使我替换未定义的字符)。

为什么会这样?如何避免?

【问题讨论】:

  • 删除了整个文件引用,它们没有必要
  • 好的,如果"sar\xE0".b 是您的输入,您的预期输出是什么?
  • 应该是sarà,但这是一个例子......不要认为是相关的。
  • "sarà" UTF-8 还是 ISO-8859-1 编码?
  • 我需要 ISO-8859-1

标签: ruby encoding utf-8


【解决方案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>

【讨论】:

  • 所以基本上我的问题是我想直接从“ASCII-8BIT”跳转到另一个?
  • @ciaoben 将二进制字符串的编码设置为 ISO-8859-1,您只需调用force_encoding('ISO-8859-1'),如上所示。您是否面临其他问题?
  • Nono 你的解决方案是有意义的。只是想理解,因为当尝试直接从 ascii-8bit 编码时,它给了我一个“双重转换”。它尝试执行 ASCII-8BIT -> UTF-8 -> ISO-8859-1(请参阅问题中的错误)
  • @ciaoben 是的,似乎 Ruby 正在尝试将 UTF-8 转换为通用“基础”,但这不会导致转换失败。问题是没有默认的二进制编码映射——字节可能意味着任何东西。但是有一个例外:encode(使用二进制)如果所有字节都在 0 到 127 之间,则确实有效,因为它们几乎以任何编码映射到相同的字符。但是,如果字符串包含 128 到 255 之间的字节,则会失败。在这种情况下,您必须告诉 encode 字符串的实际编码。
猜你喜欢
  • 1970-01-01
  • 2011-10-26
  • 2011-06-19
  • 2020-05-25
  • 1970-01-01
  • 2013-04-19
  • 1970-01-01
  • 2011-08-23
  • 2014-08-26
相关资源
最近更新 更多