相同的字符串,不同的编码,但在Ruby中不相等

时间:2014-02-08 15:56:53

标签: ruby utf-8 character-encoding ascii-8bit

任何人都可以解释这段代码发生了什么吗?

s1 = "\x20".force_encoding 'UTF-8'
s2 = "\x20".force_encoding 'ASCII-8BIT'
puts "s1 == s2: #{s1 == s2}"

s3 = "\xAB".force_encoding 'UTF-8'
s4 = "\xAB".force_encoding 'ASCII-8BIT'
puts "s3 == s4: #{s3 == s4}"

在Ruby 2.0.0p353中,它打印:

s1 == s2: true
s3 == s4: false

我不明白为什么当s1和s2为s3时s3和s4不相等。 0xAB是'½'的ASCII码,据我所知,在ASCII-8BIT和UTF8中都可以表示。

1 个答案:

答案 0 :(得分:3)

中的{p> \xAB 中的\xAB不同,因为要编码 utf-8 以多字节集编码,从\x80\xff的字符用于编码代码超过\x80的符号。

但由于 ASCII-8BIT 不是特定编码,但可以视为基于的编码类,并且它被别名为编码。从\x80\xff的代码也不能转换为任何编码。所以它就像是基于 ASCII 的代码页的抽象。

因此,如果您尝试从 ASCII-8BIT 转换为 utf-8 ,您将获得转换异常:

Encoding::UndefinedConversionError: "\xC9" from ASCII-8BIT to UTF-8

但是,您可以使用显式设置的代码页以及char ½按8位编码正确处理\xBD符号,如下所示:

"\xBD".force_encoding('ISO-8859-1').encode('UTF-8')
# => "½"
"\xBD".force_encoding('CP1252').encode('UTF-8')
# => "½"