Mat*_*att 10 ruby string unicode encoding utf-8
要将字符串转换为UTF-8并替换所有编码错误,您可以执行以下操作:
str.encode('utf-8', :invalid=>:replace)
唯一的问题是,如果str已经是UTF-8,它就不起作用,在这种情况下,任何错误仍然存在:
irb> x = "foo\x92bar".encode('utf-8', :invalid=>:replace)
=> "foo\x92bar"
irb> x.valid_encoding?
=> false
引用Ruby Docs:
请注意,从编码
enc到相同编码的转换enc是无操作,即接收器在没有任何更改的情况下返回,并且即使存在无效字节也不会引发异常.
显而易见的解决方法是首先转换为不同的Unicode编码,然后再转换回UTF-8:
str.encode('utf-16', :invalid=>:replace).encode('utf-8')
例如:
irb> x = "foo\x92bar".encode('utf-16', :invalid=>:replace).encode('utf-8')
=> "foo?bar"
irb> x.valid_encoding?
=> true
有没有更好的方法来做到这一点而不转换为虚拟编码?
mat*_*att 14
Ruby 2.1添加了一个String#scrub执行您想要的方法:
2.1.0dev :001 > x = "foo\x92bar"
 => "foo\x92bar" 
2.1.0dev :002 > x.valid_encoding?
 => false 
2.1.0dev :003 > y = x.scrub
 => "foo?bar" 
2.1.0dev :004 > y.valid_encoding?
 => true 
相同的提交也会改变行为,encode以便在源和目标编码相同时它起作用:
2.1.0dev :005 > x = "foo\x92bar".encode('utf-8', :invalid=>:replace)
 => "foo?bar" 
2.1.0dev :006 > x.valid_encoding?
 => true 
据我所知,在2.1之前没有内置的方法来执行此操作(否则scrub将不需要),因此您需要使用一些解决方法技术,直到2.1发布并且您可以升级.
尝试这个:
 "foo\x92bar".chars.select(&:valid_encoding?).join
  # => "foobar"
或者更换
"foo\x92bar".chars.map{|c| c.valid_encoding? ? c : "?"}.join
 # =>  "foo?bar"
| 归档时间: | 
 | 
| 查看次数: | 3575 次 | 
| 最近记录: |