【问题标题】:recursively convert hash containing non-UTF chars to UTF递归地将包含非 UTF 字符的哈希转换为 UTF
【发布时间】:2011-11-15 14:06:24
【问题描述】:

我有一个流氓 gem (omniauth),它提供包含我想转换为 UTF 的 ASCII-BIT8 字符串的数据哈希。

如何将哈希的所有字符串元素强制转换为 UTF,作为某种 rails 初始化方法? .to_utf8

初始化程序

session[:omniauth] = omniauth.to_utf8

class Hash
  def to_utf8
    #not really sure what to do here?
  end
end

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 hash omniauth


    【解决方案1】:

    试试这个:

    json_string = not_encoded_hash.to_json.dup.encode("UTF-8")
    encoded_hash = JSON.parse(json_string).with_indifferent_access
    

    【讨论】:

    • to_json 在非 utf8 ruby​​ 哈希上会抛出 source sequence is illegal/malformed utf-8
    【解决方案2】:

    在 Ruby 1.9 中,您通常可以使用 encode 方法翻转编码。对此进行递归转换的包装器,与symbolize_keys 不同,使这变得简单:

    class Hash
      def to_utf8
        Hash[
          self.collect do |k, v|
            if (v.respond_to?(:to_utf8))
              [ k, v.to_utf8 ]
            elsif (v.respond_to?(:encoding))
              [ k, v.dup.encode('UTF-8') ]
            else
              [ k, v ]
            end
          end
        ]
      end
    end
    

    【讨论】:

    • 看起来应该可以完美运行,但我收到来自 ASCII-8BIT 的转换错误,不知道为什么。它在控制台上运行良好。用户中的编码::UndefinedConversionError::OmniauthCallbacksController#google_apps "\xC3" 从 ASCII-8BIT 到 UTF-8
    • 这应该有一个等效的 UTF-8 (Ã) 但似乎默认情况下不支持这种转换。你可能会有更好的运气:v.dup.force_encoding('WINDOWS-1252').encode('UTF-8')
    • 那个 elsif 会尝试复制一个符号并且在其他情况下会出错。对我来说,以下工作更好elsif (v.respond_to?(:force_encoding)) [ k, v.dup.force_encoding('UTF-8') ]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-03
    • 2011-06-25
    相关资源
    最近更新 更多