我试图在一组数组中检测某个字符串时遇到了一个奇怪的问题。谁知道这里发生了什么?
(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"
答案 0 :(得分:7)
您的字符串在开头包含3个字节(BOM),表示编码为UTF-8。
问:什么是BOM?
A:字节顺序标记(BOM)由字符代码U + FEFF组成 数据流的开头,它可以用作签名 定义字节顺序和编码形式,主要是未标记的 明文文件。在某些更高级别的协议下,可以使用BOM 必须(或禁止)在定义的Unicode数据流中 该协议。
答案 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类文档非常重要,以了解处理这些类型文件的正确方法。