【发布时间】:2012-04-29 08:13:02
【问题描述】:
我有一个从某种输入中读取的字符串。
据我所知,它是 UTF8。好的:
string.force_encoding("utf8")
但是如果这个字符串中有实际上不是合法 UTF8 的字节,我现在想知道并采取行动。
通常情况下, force_encoding("utf8") 遇到这样的字节会引发吗?我相信不会。
如果我正在执行#encode,我可以从方便的选项中选择如何处理源编码(或目标编码)中无效的字符。
但我不是在做#encode,而是在做#force_encoding。它没有这样的选择。
这样做有意义吗
string.force_encoding("utf8").encode("utf8")
立即获得例外?通常编码 from utf8 to 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 - 但如果那里有无效字节,我可能想提出,或者我可能想用无效字节替换替换字符。
难道没有办法让 ruby 做到这一点吗?
更新 我相信这最终被添加到 ruby 2.1 中,2.1 预览版中存在 String#scrub 来执行此操作。所以找那个!
【问题讨论】: