我有一个 Rails 应用程序从 Rails 版本 1 开始迁移,我想忽略它上面的所有 无效字节序列,以保持向后兼容性。
我不知道输入编码。
例子:
> "- Men\xFC -".split("n")
ArgumentError: invalid byte sequence in UTF-8
from (irb):4:in `split'
from (irb):4
from /home/fotanus/.rvm/rubies/ruby-2.0.0-rc2/bin/irb:16:in `<main>'
我可以在一行中解决这个问题,例如:
> "- Men\xFC -".unpack("C*").pack("U*").split("n")
=> ["- Me", "ü -"]
但是我想始终忽略无效的字节序列并禁用此错误。在 Ruby 本身或 Rails 中。
最佳答案
我认为您无法轻松地在全局范围内关闭 UTF-8 检查。相反,我会专注于修复所有进入您的应用程序的字符串,在它们进入的边界处(例如,当您查询数据库或接收 HTTP 请求时)。
让我们假设传入的字符串具有 BINARY(又名 ASCII-8BIT 编码)。这可以像这样模拟:
s = "Men\xFC".force_encoding('BINARY') # => "Men\xFC"
然后我们可以使用 String#encode 将它们转换为 UTF-8并用 UTF-8 替换字符替换任何未定义的字符:
s = s.encode("UTF-8", invalid: :replace, undef: :replace) # => "Men\uFFFD"
s.valid_encoding? # => true
不幸的是,上述步骤最终会破坏大量 UTF-8 代码点,因为其中的字节将无法识别。如果你有一个像“\uFFFD”这样的三字节 UTF-8 字符,它将被解释为三个单独的字节,并且每个字节都会被转换为替换字符。也许你可以这样做:
def to_utf8(str)
str = str.force_encoding("UTF-8")
return str if str.valid_encoding?
str = str.force_encoding("BINARY")
str.encode("UTF-8", invalid: :replace, undef: :replace)
end
这是我能想到的最好的。不幸的是,我不知道有什么好方法可以告诉 Ruby 将字符串视为 UTF-8 并只替换所有无效字节。
关于ruby-on-rails - 如何全局忽略 UTF-8 字符串中的无效字节序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16987575/