【问题标题】:How can I check if a binary string is UTF-8 in mysql?如何在mysql中检查二进制字符串是否为UTF-8?
【发布时间】:2011-01-13 01:51:55
【问题描述】:

我找到了一个 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。

【问题讨论】:

    标签: mysql regex utf-8


    【解决方案1】:

    如果您控制该数据库的输入端和输出端,那么您应该能够在您喜欢的任何一侧验证您的数据是否为 ​​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 并让它工作,然后查看存储过程。

    【讨论】:

    • 我无法移植像 \x61 这样的字符的十六进制表示形式,请参阅我所指的问题了解更多详情
    • @Piotr Czapla - 您能告诉我您要存储哪些数据以及为什么需要以十六进制存储它吗?这可能会帮助我或其他人弄清楚。你用什么类型的字段来存储这个? (文本|二进制|varchar)。我也在扩展我的答案——看看这是否有帮助。
    • @Shame 我没有以十六进制存储任何数据。我正在修复损坏的数据库我需要检查修复转换是否正常工作。为此,我想将问题中引用的正则表达式移植到 mysql。正则表达式使用字符的十六进制表示来定义有效 utf 字符的值范围。而且mysql不支持十六进制表示。我需要想办法解决这个问题。
    【解决方案2】:

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

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

    这是支票的样子:

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

    【讨论】:

    • 这仅适用于西欧语言,例如英语、西班牙语等。如果您在其中有东方字符,则可能无法使用。
    猜你喜欢
    • 2014-03-18
    • 2016-07-01
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    • 2022-10-13
    • 2018-09-03
    • 2013-08-16
    相关资源
    最近更新 更多