在 IRB 中,我正在尝试以下操作:
1.9.3p194 :001 > foo = "\xBF".encode("utf-8", :invalid => :replace, :undef => :replace)
=> "\xBF"
1.9.3p194 :002 > foo.match /foo/
ArgumentError: invalid byte sequence in UTF-8
from (irb):2:in `match'
知道出了什么问题吗?
最佳答案
我猜 "\xBF"
已经认为它是用 UTF-8 编码的,所以当你调用 encode
时,它认为你正在尝试编码一个UTF-8 中的 UTF-8 字符串,什么都不做:
>> s = "\xBF"
=> "\xBF"
>> s.encoding
=> #<Encoding:UTF-8>
\xBF
不是有效的 UTF-8,所以这当然是无稽之谈。但是如果你使用 encode
的三参数形式:
encode(dst_encoding, src_encoding [, options] ) → str
[...] The second form returns a copy of
str
transcoded fromsrc_encoding
todst_encoding
.
您可以通过告诉 encode
忽略字符串认为其编码是什么并将其视为二进制数据来强制解决此问题:
>> foo = s.encode('utf-8', 'binary', :invalid => :replace, :undef => :replace)
=> "�"
其中s
是上面认为是UTF-8的"\xBF"
。
你也可以使用 force_encoding
在 s
上强制它是二进制的,然后使用双参数 encode
:
>> s.encoding
=> #<Encoding:UTF-8>
>> s.force_encoding('binary')
=> "\xBF"
>> s.encoding
=> #<Encoding:ASCII-8BIT>
>> foo = s.encode('utf-8', :invalid => :replace, :undef => :replace)
=> "�"
关于Ruby String.encode 仍然给出 "invalid byte sequence in UTF-8",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10466161/