我有一个字符串,我从某种输入中读取。ruby 1.9,force_encoding,但是检查
据我所知,它是UTF8。好的:
string.force_encoding("utf8")
但是,如果这个字符串中包含的字节实际上不是合法的UTF8,我现在想知道并采取行动。
通常情况下,force_encoding(“utf8”)会遇到这样的字节?我认为它不会。
如果我在做#encode,我可以从方便的选项中选择如何处理在源编码(或目标编码)中无效的字符。
但我没有做#encode,我正在做一个#force_encoding。它没有这样的选择。
会是有意义的
string.force_encoding("utf8").encode("utf8")
得到一个例外,对吗?正常编码从 utf8 到 utf8没有任何意义。但是,如果有无效字节,这可能是马上让它立即升起的方法吗?或者使用:replace
选项等来做一些与无效字节不同的东西?
但是,不,似乎也无法做到这一点。
有人知道吗?
1.9.3-p0 :032 > a = "bad: \xc3\x28 okay".force_encoding("utf-8")
=> "bad: \xC3(okay"
1.9.3-p0 :033 > a.valid_encoding?
=> false
好吧,但我如何找到并消除这些坏字节?奇怪的是,这不会提高:
1.9.3-p0 :035 > a.encode("utf-8")
=> "bad: \xC3(okay"
如果我转换到不同的编码,它会!
1.9.3-p0 :039 > a.encode("ISO-8859-1")
Encoding::InvalidByteSequenceError: "\xC3" followed by "(" on UTF-8
或者如果我告诉它,它会用“?”代替它。 =>
1.9.3-p0 :040 > a.encode("ISO-8859-1", :invalid => :replace)
=> "bad: ?(okay"
因此Ruby的得到了智慧知道什么是坏字节UTF-8,然后用别的东西来代替他们的 - 转换为不同的编码时。但我不想想要转换为不同的编码,我想留在utf8 - 但我可能想提出如果有一个无效的字节在那里,或者我可能想用替换字符替换无效的字节。
难道没有办法让ruby做到这一点吗?
更新我相信这最终被添加到2.1中的ruby中,在2.1预览版本中使用String#scrub来执行此操作。所以找那个!
使用Ruby 1.9.3-p484,这错误地将ISO-8859-1文件中的\ xc0字节标记为不正确的编码。我发现,对于我的少数测试用例,编码('binary',:undef =>:replace)似乎工作:iso-8859-1通过,但是序列不正确的UTF-8文件是抓住。 – 2014-02-10 19:56:06
查看[这个新答案](http://stackoverflow.com/a/21686992/238886)的代码,不会遇到我上面提到的问题。 – 2014-02-10 20:46:22