无效的UTF-8 Ruby字符串

无效的UTF-8 Ruby字符串,ruby,Ruby,我在Ruby(v2.5.3)处理编码字符串的方式和YAML解析器的方式上遇到了一些奇怪的行为和不一致性。下面是一个例子: "\x80" # Returns "\x80" "\x80".bytesize # Returns 1 "\x80".bytes # Returns [128] "\x80".encoding # Returns UTF-8 YAML.load('{value: "\x80"}')["value"] # Returns "\u008

我在Ruby(v2.5.3)处理编码字符串的方式和YAML解析器的方式上遇到了一些奇怪的行为和不一致性。下面是一个例子:

"\x80"          # Returns "\x80"
"\x80".bytesize # Returns 1
"\x80".bytes    # Returns [128]
"\x80".encoding # Returns UTF-8

YAML.load('{value: "\x80"}')["value"]          # Returns "\u0080"
YAML.load('{value: "\x80"}')["value"].bytesize # Returns 2
YAML.load('{value: "\x80"}')["value"].bytes    # Returns [194, 128]
YAML.load('{value: "\x80"}')["value"].encoding # Returns UTF-8
我对UTF-8的理解是,任何高于
0x7F
的单字节值都应编码为两个字节。因此,我的问题如下:

  • 单字节字符串
    “\x80”
    是否有效UTF-8
  • 如果是这样,为什么YAML会转换成两字节模式
  • 如果不是,为什么Ruby声称编码是UTF-8,但包含无效的字节序列
  • 有没有办法让YAML解析器和Ruby字符串以相同的方式工作
  • 它不是有效的UTF-8

    "\x80".valid_encoding?
    # false
    
    Ruby声称它是UTF-8,因为默认情况下所有字符串文本都是UTF-8,即使这使它们无效

    我认为您不能强制YAML解析器返回无效的UTF-8。但是要让Ruby转换这个字符,你可以这样做

    "\x80".b.ord.chr('utf-8')
    # "\u0080"
    
    .b
    仅在Ruby 2+中可用。您需要使用
    强制编码
    否则。

    “\x80”。有效的编码?
    肯定无效。虽然我不确定YAML在做什么,但我认为当您试图设置它时,它会抛出一个错误或其他东西,但我猜它只是允许字符串,并表示如果您费心检查它,它是无效的。