我有一个从某种输入中读取的字符串。
据我所知,它是 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 中的坏字节,并用其他东西替换 em - 当转换为不同的编码时。但我不想转换为不同的编码,我想保留 utf8 - 但如果那里有无效字节,我可能想提高,或者我可能想用替换字符替换无效字节。
没有办法让红宝石做到这一点吗?
更新我相信这最终已在 2.1 中添加到 ruby 中,在 2.1 预览版中存在 String#scrub 来执行此操作。所以找那个!