代码之家  ›  专栏  ›  技术社区  ›  Piotr Czapla

mysql中regexp匹配中的十六进制字符

  •  5
  • Piotr Czapla  · 技术社区  · 15 年前

    我发现了mysql非常奇怪的行为。 下面的选择返回0:

    SELECT CONVERT('a' USING BINARY) REGEXP '[\x61]'
    

    但是,语义相同的select DOWN返回1:

    SELECT CONVERT('a' USING BINARY) REGEXP '[\x61-\x61]'
    

    你知道这里发生了什么吗?

    我需要十六进制字符来创建一个regexp,当二进制字符串以utf8编码时,该regexp匹配。可以在上找到此类regexp的perl版本 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;
    
    4 回复  |  直到 15 年前
        1
  •  4
  •   Mark Byers    15 年前

    这也符合:

    SELECT CONVERT('a' USING BINARY) REGEXP '[1-\x]'
    

    \x 被解释为 x a 介于 1 . 正则表达式的其余部分只是普通字符,与此处无关,因为它们已经在[1-x]范围内。

    SELECT CONVERT('0' USING BINARY) REGEXP '[\x61-\x61]' -- Fails, because 0 < 1.
    SELECT CONVERT('1' USING BINARY) REGEXP '[\x61-\x61]' -- Succeeds: inside [1-x].
    SELECT CONVERT('2' USING BINARY) REGEXP '[\x61-\x61]' -- Succeeds: inside [1-x].
    ...
    SELECT CONVERT('w' USING BINARY) REGEXP '[\x61-\x61]' -- Succeeds: inside [1-x].
    SELECT CONVERT('x' USING BINARY) REGEXP '[\x61-\x61]' -- Succeeds: inside [1-x].
    SELECT CONVERT('y' USING BINARY) REGEXP '[\x61-\x61]' -- Fails, because y > x.
    

    SELECT HEX('a')
    61
    
        2
  •  4
  •   Puggan Se    9 年前

    编写一个类似于 [\x61-\x65] 在mysql中,可以在concat中使用十六进制值:

    SELECT CONVERT('a' USING BINARY) REGEXP CONCAT('[', 0x61, '-', 0x65, ']')
    
        3
  •  3
  •   Shorin    14 年前

    [^ -~]
    

    [^\x20-\x7E]
    
        4
  •  0
  •   Samuel Åslund mike3996    6 年前

    mysql> SELECT count(*) from myTable where CONVERT(myCol  USING BINARY) REGEXP CONCAT('[',0xF0,'-',0xFF,']','[', 0x80, '-', 0xBF, ']') limit 3;
    +----------+
    | count(*) |
    +----------+
    |        0 |
    +----------+
    1 row in set (0.54 sec)
    
    mysql> SELECT count(*) from myTable where CONVERT(myCol  USING BINARY) REGEXP CONCAT('[',0xE0,'-',0xEF,']','[', 0x80, '-', 0xBF, ']') limit 3;
    +----------+
    | count(*) |
    +----------+
    |        0 |
    +----------+
    1 row in set (0.53 sec)
    
    mysql> SELECT count(*) from myTable where CONVERT(myCol  USING BINARY) REGEXP CONCAT('[',0xC2,'-',0xDF,']','[', 0x80, '-', 0xBF, ']') limit 3;
    +----------+
    | count(*) |
    +----------+
    |        0 |
    +----------+
    1 row in set (0.50 sec)
    
    mysql> 
    

    当我不计算行数时,限制是存在的,反转regexp中的最后一个范围显示那里实际上有扩展字符(让我相信regexp可以工作,因为它还没有为我找到任何损坏的数据)。 裁判: https://www.fileformat.info/info/unicode/utf8.htm