ruby 1.9 中有没有办法从字符串中删除无效的字节序列?
Posted
技术标签:
【中文标题】ruby 1.9 中有没有办法从字符串中删除无效的字节序列?【英文标题】:Is there a way in ruby 1.9 to remove invalid byte sequences from strings? 【发布时间】:2012-02-01 09:14:32 【问题描述】:假设你有一个像"€foo\xA0"
这样的字符串,编码为UTF-8,有没有办法从这个字符串中删除无效的字节序列? (所以你得到"€foo"
)
在 ruby-1.8 中,您可以使用 Iconv.iconv('UTF-8//IGNORE', 'UTF-8', "€foo\xA0")
,但现在已弃用。 "€foo\xA0".encode('UTF-8')
什么都不做,因为它已经是 UTF-8。我试过了:
"€foo\xA0".force_encoding('BINARY').encode('UTF-8', :undef => :replace, :replace => '')
产生
"foo"
但这也失去了有效的多字节字符€
【问题讨论】:
【参考方案1】:"€foo\xA0".encode('UTF-16le', invalid: :replace, replace: '').encode('UTF-8')
【讨论】:
我的印象是它的字符集比 UTF-8 更大,这意味着您不会丢失任何有效数据。不幸的是,以下内容不起作用:"€foo\xA0".encode('UTF-8', :invalid => :replace, :replace => '')
因为字符串已经是 UTF-8,所以不会再次编码。
FWIW,在一个大文件上运行测试我发现这种方法比valid_encoding
方法快一个数量级。
UTF-8 和 UTF-16 都可以表示所有 Unicode 字符。唯一的区别是字符的编码方式。
所有 UTF 编码同样能够编码所有可能的 Unicode 字符; UTF-8、UTF-16 和 UTF-32 在这方面没有区别。唯一实际的区别是output size。
用这个字符串抛出一个错误:"eEspa\xF1a;FB"
【参考方案2】:
"€foo\xA0".chars.select(&:valid_encoding?).join
【讨论】:
它不会删除这个字符串"eEspa\xF1a;FB"
中的\xF1
@Dorian,在 1.9.3 IRB 控制台上,"eEspa\xF1a;FB".chars.select|i| i.valid_encoding?.join
返回"eEspaa;FB"
...您没有得到这种行为还是我误解了?【参考方案3】:
Ruby 2.0 和 1.9.3
"€foo\xA0".encode(Encoding::UTF_8, Encoding::UTF_8, :invalid => :replace)
Ruby 2.1+
"€foo\xA0".scrub
【讨论】:
【参考方案4】: data = '' if not (data.force_encoding("UTF-8").valid_encoding?)
【讨论】:
这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时评论自己的帖子,一旦您有足够的reputation,您就可以comment on any post。 @Severin 怎么没有?它看起来像是对这个问题的(不正确的)答案。它从字符串中删除所有无效的字节序列。它也会删除所有有效的。以上是关于ruby 1.9 中有没有办法从字符串中删除无效的字节序列?的主要内容,如果未能解决你的问题,请参考以下文章
Ruby 1.9:将字节数组转换为具有多字节 UTF-8 字符的字符串