2017-10-18 91 views
1

我使用Ruby 2.3:为什么UTF-8字符串不等于Ruby 2.0中相应的ASCII-8BIT字符串?

我有以下字符串:"\xFF\xFE"

我就包含它的文件做一个File.binread(),所以这个字符串的编码是ASCII-8BIT。但是,在我的代码中,我通过将字符串与"\xFF\xFE"(因为所有的Ruby字符串默认情况下编码为UTF-8)进行比较来检查该字符串是否确实被读取。

然而,比较返回false,即使两个字符串包含相同的字节 - 它只是碰巧,一个是与编码ASCII-8BIT,另一个是UTF-8

我有两个问题:(1)为什么它的回报false? (2)什么是实现我想要的最好方法?我只想检查我读的字符串是否匹配"\xFF\xFE"

+0

如果你只是想读取一个Unicode文件BOM,您可以传递BOM的UTF-8的[encoding](http://ruby-doc.org/core-2.4.2/IO.html#method-c-new-label-IO+Encoding) “让Ruby自动处理它。 – Stefan

回答

4

(1)为什么它返回false

比较字符串时,它们必须是相同的编码,或者它们的字符必须在US-ASCII中可编码。

比较将按预期如果字符串仅包含字节值0至127:(0b0xxxxxxx

a = 'E'.encode('ISO8859-1') #=> "E" 
b = 'E'.encode('ISO8859-15') #=> "E" 

a.bytes #=> [69] 
b.bytes #=> [69] 
a == b #=> true 

而如果它包含任何字节值失败128至255:(0b1xxxxxxx

a = 'É'.encode('ISO8859-1') #=> "\xC9" 
b = 'É'.encode('ISO8859-15') #=> "\xC9" 

a.bytes #=> [201] 
b.bytes #=> [201] 
a == b #=> false 

您的字符串不能用US-ASCII表示,因为它的字节在其范围之外:

"\xFF\xFE".bytes #=> [255, 254] 

试图转换它不产生任何有意义的结果:

"\xFF\xFE".encode('US-ASCII', 'ASCII-8BIT', :undef => :replace) 
#=> "??" 

字符串因此将返回false被比较,以另一种编码的字符串时,无论其内容。

(2)什么是最好的方式去实现我想要的?

您可以将您的字符串与具有相同编码的字符串进行比较。 binread返回一个字符串在ASCII-8BIT编码,因此您可以使用b来创建一个兼容的一个:

IO.binread('your_file', 2) == "\xFF\xFE".b 

,或者你可以比较其bytes

IO.binread('your_file', 2).bytes == [0xFF, 0xFE] 
+0

但它的8位ascii和字符255和254被定义。那么,那是怎么回事? ' “\ XFF \ xFE如果”。编码('ASCII-8BIT')'工作得很好。是否因为它不是有效的UTF-8? – horseyguy

+3

没有“8位ascii”这样的东西。 ASCII一直是,并且一直是7位。 –

+0

@banister你把'ASCII-8BIT'和'US-ASCII'混淆了,我的回答在这方面也不是很精确。我已经相应地更新了它。 – Stefan

相关问题