为了将字符串转换为 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 :
Please note that conversion from an encoding
enc
to the same encodingenc
is a no-op, i.e. the receiver is returned without any changes, and no exceptions are raised, even if there are invalid bytes.
明显的解决方法是先转换为不同的 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
有没有更好的方法在不转换为虚拟编码的情况下执行此操作?
最佳答案
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 发布之前您需要使用一些解决方法,并且你可以升级。
关于ruby - 如何在不转换为不同编码的情况下替换 Ruby 中的 UTF-8 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19164254/