如何在mysql中检查二进制字符串是否为UTF-8?

时间:2010-02-04 13:05:47

标签: mysql regex utf-8

我找到了一个Perl正则表达式,可以检查字符串是否为UTF-8(正则表达式来自w3c site)。

$field =~
  m/\A(
     [\x09\x0A\x0D\x20-\x7E]            # ASCII
   | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
   |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
   | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
   |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
   |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
   | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
   |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
  )*\z/x;

但我不确定如何将其移植到MySQL,因为似乎MySQL不支持字符的十六进制表示,请参阅this question

有关如何将正则表达式移植到MySQL的任何想法? 或者您可能知道其他任何方法来检查字符串是否有效UTF-8?

更新 我需要在MySQL上进行此检查,因为我需要在服务器上运行它以纠正损坏的表。我不能通过脚本传递数据,因为数据库大约是1TB。

2 个答案:

答案 0 :(得分:3)

我已经设法使用一个测试来修复我的数据库,该测试仅在我的情况下使用单字节编码表示数据时才有效。它是latin1。

我已经使用了mysql将非utf-8的字节更改为'?'的事实转换为latin1时。

以下是支票的外观:

SELECT (
         CONVERT(
           CONVERT(
              potentially_broken_column 
           USING latin1) 
         USING utf8))
       != 
       potentially_broken_column) AS INVALID ....

答案 1 :(得分:0)

如果您控制此DB的输入和输出端,那么您应该能够在您喜欢的任何一方验证您的数据是UTF-8,并根据需要实施约束。如果你正在处理一个你不控制输入端的系统,那么在你拔出它之后你将不得不检查它,并且可能用您选择的语言进行转换(Perl听起来像)。

数据库是一个非常好的存储设施,但不应该积极地用于其他应用程序。我认为这是一个你应该让MySQL保存数据的地方,直到你需要用它做更多的事情。

如果您想继续沿着您所在的路径行驶,请查看此MySQL手册页:http://dev.mysql.com/doc/refman/5.0/en/regexp.html

REGEX在语言之间通常非常相似(实际上我几乎总是可以在JavaScript,PHP和Perl之间进行复制,只需对其包装函数进行微小调整),所以如果它正在运行REGEX,那么你应该能够轻松地移植它。

GL!

编辑:看看这篇Stack文章 - 考虑到你不能使用脚本来处理数据,你可能想要使用存储过程:Regular expressions in stored procedures

使用存储过程,您可以遍历数据并执行大量处理,而无需离开MySQL。第二篇文章将引用你回到我列出的那篇文章,所以我认为你需要首先证明你的REGEX并让它工作,然后查看存储过程。