gpt4 book ai didi

ruby-on-rails - rails : encoding woes with serialized hashes despite UTF8

转载 作者:数据小太阳 更新时间:2023-10-29 06:48:11 28 4
gpt4 key购买 nike

我刚刚从 ruby​​ 1.9.2 更新到 ruby​​ 1.9.3p0(2011-10-30 修订版 33570)。我的 Rails 应用程序使用 postgresql 作为其数据库后端。系统区域设置为 UTF8,数据库编码也是如此。 Rails 应用程序的默认编码也是 UTF8。我有中国用户输入汉字和英文字符。字符串存储为 UTF8 编码字符串。

rails 版本:3.0.9

自更新以来,数据库中的一些现有中文字符串不再正确显示。这不会影响所有字符串,只会影响那些属于序列化哈希的字符串。存储为普通字符串的所有其他字符串看起来仍然是正确的。


示例:

这是一个序列化的散列,在数据库中存储为 UTF8 字符串:

broken = "--- !map:ActiveSupport::HashWithIndifferentAccess \ncheckbox: \"1\"\nchoice: \"Round Paper Clips  \\xEF\\xBC\\x88\\xE5\\x9B\\x9E\\xE5\\xBD\\xA2\\xE9\\x92\\x88\\xEF\\xBC\\x89\\r\\n\"\ninfo: \"10\\xE7\\x9B\\x92\"\n"

为了将此字符串转换为 ruby​​ 哈希,我使用 YAML.load 对其进行了反序列化。 :

broken_hash = YAML.load(broken)

这会返回一个包含乱码内容的散列:

{"checkbox"=>"1", "choice"=>"Round Paper Clips  ï¼\u0088å\u009B\u009Eå½¢é\u0092\u0088ï¼\u0089\r\n", "info"=>"10ç\u009B\u0092"}

乱码应该是UTF8编码的中文。 broken_hash['info'].encoding告诉我 ruby 认为这是 #<Encoding:UTF-8> .我不同意。

有趣的是,之前未序列化的所有其他字符串看起来都很好。在同一条记录中,不同的字段包含看起来恰到好处的汉字——在 rails 控制台、psql 控制台和浏览器中。每个字符串——无论是序列化哈希还是纯字符串——都保存到数据库中,因为更新看起来也很好。


我试图将乱码文本从可能错误的编码(如 GB2312 或 ANSI)转换为 UTF-8,尽管 ruby​​ 声称这已经是 UTF-8,当然我失败了。这是我使用的代码:

require 'iconv'
Iconv.conv('UTF-8', 'GB2312', broken_hash['info'])

这会失败,因为 ruby​​ 不知道如何处理字符串中的非法序列。

我真的只是想运行一个脚本来修复所有旧的、可能已损坏的序列化哈希字符串并完成它。有没有办法把这些断掉的字符串重新转换成类似中文的东西?


我只是在原始字符串中使用编码的 UTF-8 字符串(在上例中称为“broken”)。这是编码在序列化字符串中的中文字符串:

chinese = "\\xEF\\xBC\\x88\\xE5\\x9B\\x9E\\xE5\\xBD\\xA2\\xE9\\x92\\x88\\xEF\\xBC\\x89\\r\\n\"

我注意到通过取消转义(删除转义反斜杠)可以很容易地将其转换为真正的 UTF-8 编码字符串。

chinese_ok = "\xEF\xBC\x88\xE5\x9B\x9E\xE5\xBD\xA2\xE9\x92\x88\xEF\xBC\x89\r\n"

这将返回一个正确的 UTF-8 编码的中文字符串:"(回形针)\r\n"

只有当我使用 YAML.load(...) 时,它才会崩溃将字符串转换为 ruby​​ 哈希。也许我应该在将原始字符串提供给 YAML.load 之前对其进行处理.只是让我想知道为什么会这样......


有趣!这可能是由于现在在 1.9.3 中默认使用的 YAML 引擎“psych”。我用 YAML::ENGINE.yamler = 'syck' 切换到“syck”引擎并且正确解析了损坏的字符串。

最佳答案

这似乎是由两个可用的 YAML 引擎“syck”和“psych”的行为差异引起的。将 YAML 引擎设置为 syck:

YAML::ENGINE.yamler = 'syck'

将 YAML 引擎设置回 psych:

YAML::ENGINE.yamler = 'psych'

“syck”引擎按预期处理字符串并将它们转换为具有适当中文字符串的散列。当使用“psych”引擎(ruby 1.9.3 中的默认引擎)时,转换会导致字符串出现乱码。

将以上行(两行中的第一行)添加到 config/application.rb 可以解决此问题。 “syck”引擎不再维护,所以我可能应该只使用此解决方法来争取一些时间来使字符串为“psych”所接受。

关于ruby-on-rails - rails : encoding woes with serialized hashes despite UTF8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8558101/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com