【问题标题】:What is the difference between #encode and #force_encoding in ruby?ruby 中的#encode 和#force_encoding 有什么区别?
【发布时间】:2014-02-06 21:17:43
【问题描述】:

我真的不明白String 类在Ruby 中#encode#force_encoding 之间的区别。我知道"kam".force_encoding("UTF-8") 会强制"kam" 使用UTF-8 编码,但#encode(encoding) 有何不同?

http://ruby-doc.org/core-2.0/String.html#method-i-encoding

【问题讨论】:

  • 你说的是String#encode还是String#encoding?我猜String#encode 但你提到了这两种方法并链接到String#encoding

标签: ruby encoding


【解决方案1】:

差异很大。 force_encoding 设置给定的字符串编码,但不改变字符串本身,即不改变它在内存中的表示:

'łał'.bytes #=> [197, 130, 97, 197, 130]
'łał'.force_encoding('ASCII').bytes #=> [197, 130, 97, 197, 130]
'łał'.force_encoding('ASCII')   #=> "\xC5\x82a\xC5\x82"

encode 假定当前编码是正确的并尝试更改字符串,使其在第二个编码中以相同的方式读取:

'łał'.encode('UTF-16') #=> 'łał'
'łał'.encode('UTF-16').bytes #=> [254, 255, 1, 65, 0, 97, 1, 66] 

简而言之,force_encoding 改变了从字节中读取字符串的方式,encode 改变了写入字符串的方式而不改变输出(如果可能的话)

【讨论】:

    【解决方案2】:

    阅读此Changing an encoding

    可以通过两种不同的方式更改字符串的关联编码。

    首先,可以使用String#force_encoding 将字符串的Encoding 设置为新的编码,而无需更改字符串的内部字节表示。这就是告诉 Ruby 字符串的正确编码的方法。

    例子:

    string = "R\xC3\xA9sum\xC3\xA9"
    string.encoding #=> #<Encoding:ISO-8859-1>
    string.force_encoding(Encoding::UTF_8) #=> "R\u00E9sum\u00E9"
    

    其次,可以转码一个字符串,即将其内部字节表示转换为另一种编码。其关联编码也设置为其他编码。请参阅String#encode 了解各种形式的转码,并参阅Encoding::Converter 类以获得对转码过程的额外控制。

    例子:

    string = "R\u00E9sum\u00E9"
    string.encoding #=> #<Encoding:UTF-8>
    string = string.encode!(Encoding::ISO_8859_1)
    #=> "R\xE9sum\xE9"
    string.encoding
    #=> #<Encoding::ISO-8859-1>
    

    【讨论】:

      【解决方案3】:

      这是我的比喻

      • force_encoding ==> 用不同的语言说同样的事情
      • 编码 ==>用不同的语言解释相同的声音

      在哪里

      • 字节 ==> 事物
      • 编码 ==> 语言
      • 字符串输出 ==> 声音

      【讨论】:

        【解决方案4】:

        根据this blog post:In Ruby, strings are a combination of an array of bytes, and an encoding object(*)。

        x = 'Hello World' ---> <Encoding:UTF-8>
        

        调用 force_encoding 会改变原始字符串,其中 encode 创建一个具有不同编码的新字符串。

        force_encoding

        # before force_encoding
        x = 'Hello World' ---> <Encoding:UTF-8>
        
        x.force_encoding "US-ASCII"
        
        # after force_encoding
        x ---> <Encoding:US-ASCII>
        

        编码

        # before encode
        x = 'Hello World' ---> <Encoding:UTF-8>
        
        y = x.encode("US-ASCII")
        
        # after encode
        x ---> <Encoding:UTF-8>
        y ---> <Encoding:US-ASCII>
        

        Another awesome blog post (read "The Solution" part) 解释了为什么设计Ruby String &lt;Bytes + Encoding&gt; (*)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-09-06
          • 2010-11-17
          • 2010-12-16
          • 2013-06-10
          • 2011-05-17
          • 2012-09-12
          • 2010-09-24
          相关资源
          最近更新 更多