如何使用 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:将字节数组转换为具有多字节 UTF-8 字符的字符串
ruby 1.9 中有没有办法从字符串中删除无效的字节序列?