【问题标题】:Why doesn't ruby detect an invalid encoding while mysql does?为什么 ruby​​ 检测不到无效编码,而 mysql 检测到无效编码?
【发布时间】:2011-08-21 08:53:58
【问题描述】:

我从 YouTube 中提取了一些 UTF8 无效的 RSS 提要。我可以使用

创建一个类似的 ruby​​ 字符串
bad_utf8 = "\u{61B36}"
bad_utf8.encoding # => #<Encoding:UTF-8>
bad_utf8.valid_encoding? # => true

Ruby 认为这是一种有效的 UTF-8 编码,我很确定它不是。

当与 Mysql 交谈时,我得到一个这样的错误

require 'mysql2'
client = Mysql2::Client.new(:host => "localhost", :username => "root")
client.query("use test");

bad_utf8 = "\u{61B36}"
client.query("INSERT INTO utf8 VALUES ('#{moo}')")

# Incorrect string value: '\xF1\xA1\xAC\xB6' for column 'string' at row 1 (Mysql2::Error)

如何在将这些无效的编码类型发送到 MySQL 之前检测或修复它们?

【问题讨论】:

  • 所以我认为问题可能是 MySQL 只支持基本多语言平面,而 ruby​​ 支持一切。
  • Ruby 什么都支持?从什么时候开始?

标签: mysql ruby utf-8 internationalization utf8mb4


【解决方案1】:

我不依赖Ruby内置的String.valid_encoding?,因为下面的也是可以的:

irb
1.9.3-p125 :001 > bad_utf8 = "\u{0}"
 => "\u0000" 
1.9.3-p125 :002 > bad_utf8.valid_encoding?
 => true 
1.9.3-p125 :003 > bad_utf8.encoding
 => #<Encoding:UTF-8>

这是有效的 UTF-8(参考:https://en.wikipedia.org/wiki/Utf8),但我发现字符串中存在 NULL 字符通常是对先前转换错误的提示(例如,当从 html 页面中发现的无效编码信息进行转码时) )。

我为“Modified UTF-8”创建了自己的验证函数,它可以采用 :bmp_only 选项将验证限制在基本多语言平面 (0x1-0xffff)。对于大多数现代语言来说,这应该足够了(参考:https://en.wikipedia.org/wiki/Unicode_plane)。

在此处查找验证器:https://gist.github.com/2295531

【讨论】:

【解决方案2】:

可能是因为代码点不在basic multilingual plane 中 这是 MySQL 在其“utf8”字符集中唯一允许的字符。

较新版本的 mysql 有另一个名为“utf8mb4”的字符集supports unicode characters outside the BMP

但您可能不想使用它。仔细考虑您的用例。很少有真正的人类语言(如果有的话)使用 BMP 之外的字符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 2011-04-12
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多