我找到了一个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。
答案 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并让它工作,然后查看存储过程。