如何使用 ruby​​ 1.9 转换字符编码

Posted

技术标签:

【中文标题】如何使用 ruby​​ 1.9 转换字符编码【英文标题】:how to convert character encoding with ruby 1.9 【发布时间】:2011-03-10 17:44:52 【问题描述】:

我目前在使用 amazon api 的结果时遇到问题。

服务返回一个带有 unicode 字符的字符串:Mac 上的Learn Objective\xE2\x80\x93C(Learn 系列)

使用 ruby​​ 1.9.1 甚至无法处理字符串:

REXML::ParseException: #<Encoding::CompatibilityError: incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string)>

...

Exception parsing

Line: 1

Position: 1636

Last 80 unconsumed characters:

Learn Objective–C on the Mac (Learn Series)

【问题讨论】:

我强烈建议您阅读每个软件开发人员绝对、肯定必须了解 Unicode 和字符集(没有任何借口!) (joelonsoftware.com/articles/Unicode.html),即使您'已经熟悉编码等。 我最近阅读了 yehuda katz 关于 1.9 编码的文章并想:WTF?! (yehudakatz.com/2010/05/17/encodings-unabridged) 你链接的文章非常好。 【参考方案1】:

作为例外点,您的字符串是 ASCII-8BIT 编码的。您应该更改编码。对此有一个long story,但如果您对快速解决方案感兴趣,请在进行任何处理之前在字符串上添加force_encoding

s = "Learn Objective\xE2\x80\x93C on the Mac"
# => "Learn Objective\xE2\x80\x93C on the Mac"
s.encoding
# => #<Encoding:ASCII-8BIT>
s.force_encoding 'utf-8'
# => "Learn Objective–C on the Mac"

【讨论】:

这是从亚马逊服务发送的响应的问题吗?它应该设置另一个内容类型吗? 我没有使用 AWS,所以我不知道该字符串是如何加载的,但是您可以在 (Ruby) 应用程序级别设置默认编码,所以它很可能会解决问题 - 更多关于答案中的链接。顺便说一句,我认为根本没有 问题,Ruby 根本不会(也不应该)尝试猜测它正在接收的字符串是哪种编码。 可能;这意味着 HTTParty 应该处理它。【参考方案2】:

如果以 ASCII-8BIT 编码的所有内容实际上都可以直接转换为 UTF-8,则 Mladen 的解决方案有效。当存在 1) 无效或 2) 在 UTF-8 中未定义的字符时,它会中断。但是,这将起作用(在 1.9.2 及更高版本中:

new_str = s.encode('utf-8', 'binary', :invalid => :replace, 
  :undef => :replace, :replace => '')

ASCII-8BIT 实际上是二进制的。此代码将编码转换为 UTF-8,同时正确处理无效和未定义的字符。 :invalid 选项指定替换无效字符。 :undef 选项指定替换未定义的字符。 :replace 选项定义了应该用什么替换无效或未定义的字符。在这种情况下,我选择简单地删除它们。

【讨论】:

嗯,看起来不错!会试试的! 您尝试过:fallback 机制吗?我试图用 ä 替换一些 windows-1252 编码,例如 u00E4,但没有成功:( 在将文件流式传输到 HTTP 正文中以进行发布时,这为我节省了一天...非常感谢! +1 这对我来说删除了一个非常麻烦的 BOM 字符

以上是关于如何使用 ruby​​ 1.9 转换字符编码的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 Ruby 1.9 上设置默认字符串编码吗?

Ruby 1.9:将字节数组转换为具有多字节 UTF-8 字符的字符串

在 os x 上使 ruby​​ 1.9 默认 [重复]

ruby 1.9 中有没有办法从字符串中删除无效的字节序列?

如何将 UTF8 组合字符转换为 ruby​​ 中的单个 UTF8 字符?

Ruby:字符串在 1.9 中不再混入 Enumerable