任何人都知道"奇怪的"字符串开头的字符?

时间:2015-07-13 16:34:34

标签: ruby

我试图在一组数组中检测某个字符串时遇到了一个奇怪的问题。谁知道这里发生了什么?

(rdb:1) p magic_string
"Time Period"
(rdb:1) p magic_string.class
String
(rdb:1) p magic_string == "Time Period"
false
(rdb:1) p "Time Period".length
11
(rdb:1) p magic_string.length
14
(rdb:1) p magic_string[0].chr
"\357"
(rdb:1) p magic_string[1].chr
"\273"
(rdb:1) p magic_string[2].chr
"\277"
(rdb:1) p magic_string[3].chr
"T"

2 个答案:

答案 0 :(得分:7)

您的字符串在开头包含3个字节(BOM),表示编码为UTF-8。

  

问:什么是BOM?

     

A:字节顺序标记(BOM)由字符代码U + FEFF组成   数据流的开头,它可以用作签名   定义字节顺序和编码形式,主要是未标记的   明文文件。在某些更高级别的协议下,可以使用BOM   必须(或禁止)在定义的Unicode数据流中   该协议。

source

答案 1 :(得分:6)

这可以帮助您了解正在发生的事情:

# encoding: UTF-8
RUBY_VERSION # => "1.9.3"
magic_string = "Time Period"
magic_string[0].chr # => "\uFEFF"

Ruby v2.2.2也是如此。

旧版本的Ruby没有默认为UTF-8,并将字符串视为字节数组。 encoding行很重要,告诉它脚本的字符串编码是什么。

Ruby现在正确地将字符串视为字符数组而不是字节数,这就是为什么它将第一个字符报告为"\uFEFF"(一个双字节字符)的原因。

"\uFEFF""\uFFFE" BOM markers显示字符所在的“endian”。 Endianness与CPU关于一个字中最重要和最不重要的字节(通常是两个字节)的概念有关。这也与Unicode有关,这两者都是你需要理解的东西,至少是基本的方式,因为我们不再只处理ASCII,而且语言不仅仅包含拉丁字符集。

UTF-8是一个多字节字符集,包含来自多种语言的大量字符。您也可以使用UTF-16LE,UTF-16BE或更长时间;互联网上的HTML和文档可以根据原始硬件编码不同长度的字符,而不知道那些可能会让你疯狂,并且你会试图阅读他们的内容。阅读“IO Encoding”的IO类文档非常重要,以了解处理这些类型文件的正确方法。