Шестнадцатеричные символы в регулярных выражениях в MySQL - PullRequest
6 голосов
/ 04 февраля 2010

Я заметил очень странное поведение mysql.Выбор ниже возвращает 0:

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

Однако семантически идентичный выбор ниже возвращает 1:

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

Знаете ли вы, что здесь происходит?Я проверял, что в mysql 5.0.0.3031 и 4.1.22

мне нужны шестнадцатеричные символы для создания регулярного выражения, которое соответствует, когда двоичная строка кодируется в utf8.Perl-версию такого регулярного выражения можно найти на сайте w3c .Это выглядит следующим образом:

$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 ]

4 голосов
/ 11 ноября 2015

, чтобы записать регулярное выражение наподобие [\x61-\x65] в mysql, вы можете использовать шестнадцатеричные значения внутри concat:

SELECT CONVERT('a' USING BINARY) REGEXP CONCAT('[', 0x61, '-', 0x65, ']')
3 голосов
/ 04 февраля 2010

Это также соответствует:

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

Причина в том, что \x интерпретируется как x, а a находится между 1 и x.Остальная часть вашего регулярного выражения - это обычные символы, которые здесь не актуальны, потому что они уже находятся в диапазоне [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 голосов
/ 11 января 2011

Lol ... исходя из вышесказанного вы можете просто использовать печатные символы.Это сработало для меня.Я хотел, чтобы он совпадал с символами не на клавиатуре США, и следующее выражение работает на MySQL 5.1:

[^ -~]

Это будет делать то же самое, что и

[^\x20-\x7E]
0 голосов
/ 13 февраля 2019

Я хотел проверить символы в кодировке UTF-8 в столбце латиницы-1, подробно остановившись на ответе Пуггана Сэ:

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> 

Существует ограничение для случаев, когда я не считаюстроки, инвертирующие последний диапазон в регулярном выражении, показали мне, что там действительно были расширенные символы (что дает мне уверенность в том, что регулярное выражение работает, поскольку оно еще не нашло для меня поврежденных данных).Ссылка: https://www.fileformat.info/info/unicode/utf8.htm

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...