REGEXP
Описание
Проверяет строку <str> на соответствие регулярному выражению и возвращает true при совпадении и false в противном случае. Шаблон не обязан совпадать со всей строкой; для полного совпадения используйте ^ и $. Возвращает NULL, если хотя бы один аргумент равен NULL, и сообщает об ошибке, если шаблон некорректен. Строки обрабатываются в кодировке UTF-8; для сопоставления с категориями символов Unicode используйте классы символов, например \p{Han}.
Для обычных шаблонов см. синтаксис RE2.
Движки сопоставления и переменные сеанса
При обычном сопоставлении с помощью LIKE и REGEXP может использоваться ускорение Hyperscan. Следующие переменные сеанса управляют переходом на другой движок:
| Переменная сеанса | По умолчанию | Поведение |
|---|---|---|
enable_hyperscan_fallback | true | Поддерживается в серии Doris 4.1 начиная с 4.1.5. Позволяет пути выполнения, на котором действительно используется компиляция в Hyperscan, переходить на RE2 при ошибке компиляции или невозможности выделить рабочую память для сопоставления. При false возвращается соответствующая ошибка. На оптимизации простых шаблонов и пути выполнения, напрямую использующие RE2, не влияет. |
enable_extended_regex | false | Разрешает REGEXP пробовать движок Boost.Regex, если RE2 отклоняет шаблон, обеспечивая поддержку расширенного синтаксиса, например look-around. Не расширяет синтаксис RE2 и не добавляет поддержку расширенного синтаксиса в LIKE, MATCH_REGEXP или MULTI_MATCH_ANY. |
В серии Doris 4.1 начиная с 4.1.5 настройка enable_extended_regex=true применяется как к константным шаблонам, так и к неконстантным шаблонам, считываемым из столбцов. Если путь выполнения Hyperscan использует enable_hyperscan_fallback=false, сбой Hyperscan по-прежнему приводит к ошибке; включение enable_extended_regex не позволяет обойти эту ошибку.
В справочнике переменных сеанса приведены значения и область действия enable_hyperscan_fallback.
Для расширенных шаблонов см. синтаксис Perl в Boost.Regex. Дополнительные затраты на сопоставление в Boost.Regex возникают только при использовании этого движка. Сложные шаблоны, использующие backtracking, также могут приводить к ошибке Failed to match regex expression.
Ограничение числа повторений
В серии Doris 4.1 начиная с 4.1.5 для регулярного выражения, переданного в Hyperscan, компиляция в Hyperscan пропускается, если форма {m}, {m,} или {m,n} содержит число больше 50. Например, a{51}, a{51,} и a{0,51} вызывают срабатывание этой проверки, а a{50} и a{0,50} не вызывают. Проверка текста носит консервативный характер, поэтому она может сработать и для таких форм внутри классов символов или комментариев.
| Путь сопоставления | Поведение при срабатывании проверки |
|---|---|
Путь Hyperscan для обычных LIKE или REGEXP | Пытается перейти на другой движок при enable_hyperscan_fallback=true; в противном случае возвращает ошибку. Шаблон по-прежнему должен соответствовать синтаксису и ограничениям числа повторений целевого движка. |
Построчное сопоставление для MATCH_REGEXP и сопоставление по регулярному выражению с использованием инвертированного индекса | Сразу отклоняет шаблон; не использует enable_hyperscan_fallback. |
Сопоставление с несколькими шаблонами для MULTI_MATCH_ANY | Сразу отклоняет шаблон; не использует enable_hyperscan_fallback. |
Если проверка срабатывает без перехода на другой движок, сообщение об ошибке содержит:
Skip hyperscan compilation because bounded repetition exceeds 50
Синтаксис
REGEXP(<str>, <pattern>)
<str> [NOT] REGEXP <pattern>
<str> [NOT] RLIKE <pattern>
Параметры
| Параметр | Описание |
|---|---|
<str> | Строковый тип. Строка, для которой проверяется соответствие регулярному выражению; это может быть столбец таблицы или строковый литерал. |
<pattern> | Строковый тип. Шаблон регулярного выражения, используемый для сопоставления со строкой <str>. Регулярные выражения позволяют гибко задавать сложные шаблоны поиска, включая классы символов, квантификаторы и якоря. |
Возвращаемое значение
Функция REGEXP возвращает значение типа BOOLEAN. Если строка <str> соответствует шаблону регулярного выражения <pattern>, функция возвращает true (в SQL представляется как 1); в противном случае возвращает false (в SQL представляется как 0). Возвращает NULL, если хотя бы один аргумент равен NULL.
В серии Doris 4.1 начиная с 4.1.5 константные пустые шаблоны ведут себя так же, как шаблоны из столбцов: пустой шаблон соответствует любой строке, отличной от NULL, в том числе пустой строке.
Поведение по умолчанию:
| Настройка по умолчанию | Поведение |
|---|---|
. соответствует символу новой строки | . по умолчанию может соответствовать \n (символу новой строки). |
| С учётом регистра | Сопоставление выполняется с учётом регистра. |
^/$ соответствуют границам всей строки | ^ соответствует только началу всей строки, а $ соответствует только её концу, а не началу или концу отдельных строк. |
| Жадные квантификаторы | *, + и т. д. по умолчанию захватывают как можно больше символов. |
| UTF-8 | Строки обрабатываются в кодировке UTF-8. |
Модификаторы шаблона:
Чтобы изменить поведение по умолчанию, добавьте в начало pattern префикс (?flags). Несколько модификаторов можно объединить, например (?im); префикс - отключает соответствующий параметр, например (?-s).
В следующей таблице описаны модификаторы для обычного пути Hyperscan/RE2. Если из-за синтаксиса, например look-around, происходит переход на Boost.Regex, интерпретируйте модификаторы согласно синтаксису Boost.Regex; поведение движков может различаться.
| Флаг | Значение |
|---|---|
(?i) | Сопоставление без учёта регистра |
(?-i) | С учётом регистра (по умолчанию) |
(?s) | . соответствует символу новой строки (включено по умолчанию) |
(?-s) | . не соответствует символу новой строки |
(?m) | Многострочный режим: ^ соответствует началу каждой строки, $ соответствует концу каждой строки |
(?-m) | Однострочный режим: ^/$ соответствуют границам всей строки (по умолчанию) |
(?U) | Нежадные квантификаторы: *, + и т. д. захватывают как можно меньше символов |
(?-U) | Жадные квантификаторы (по умолчанию): *, + и т. д. захватывают как можно больше символов |
Пример
CREATE TABLE test ( k1 VARCHAR(255) ) properties("replication_num"="1");
INSERT INTO test (k1) VALUES ('billie eillish'), ('It\'s ok'), ('billie jean'), ('hello world');
--- Find all data in the k1 column starting with 'billie'
SELECT k1 FROM test WHERE k1 REGEXP '^billie' ORDER BY k1;
+----------------+
| k1 |
+----------------+
| billie eillish |
| billie jean |
+----------------+
--- Find data in the k1 column ending with 'ok':
SELECT k1 FROM test WHERE k1 REGEXP 'ok$';
+---------+
| k1 |
+---------+
| It's ok |
+---------+
Пример с китайскими иероглифами
select regexp('这是一段中文 This is a passage in English 1234567', '\\p{Han}');
+-----------------------------------------------------------------------------+
| ('这是一段中文 This is a passage in English 1234567' regexp '\p{Han}') |
+-----------------------------------------------------------------------------+
| 1 |
+-----------------------------------------------------------------------------+
Вставка данных и проверка простого сопоставления строк
CREATE TABLE test_regexp (
id INT,
name VARCHAR(255)
) PROPERTIES("replication_num"="1");
INSERT INTO test_regexp (id, name) VALUES
(1, 'Alice'),
(2, 'Bob'),
(3, 'Charlie'),
(4, 'David');
-- Find all names starting with 'A'
SELECT id, name FROM test_regexp WHERE name REGEXP '^A';
+------+-------+
| id | name |
+------+-------+
| 1 | Alice |
+------+-------+
Проверка сопоставления специальных символов
-- Insert names with special characters
INSERT INTO test_regexp (id, name) VALUES
(5, 'Anna-Maria'),
(6, 'John_Doe');
-- Find names containing the '-' character
SELECT id, name FROM test_regexp WHERE name REGEXP '-';
+------+------------+
| id | name |
+------+------------+
| 5 | Anna-Maria |
+------+------------+
Проверка сопоставления по окончанию строки
-- Find names ending with 'e'
SELECT id, name FROM test_regexp WHERE name REGEXP 'e$' ORDER BY id;
+------+----------+
| id | name |
+------+----------+
| 1 | Alice |
| 3 | Charlie |
| 6 | John_Doe |
+------+----------+
Проверка с эмодзи
SELECT 'Hello' REGEXP '😀';
+-----------------------+
| 'Hello' REGEXP '😀' |
+-----------------------+
| 0 |
+-----------------------+
Пустой шаблон соответствует любой строке, отличной от NULL, в том числе пустой строке:
SELECT REGEXP('abc', ''), REGEXP('', ''), REGEXP(NULL, '');
1 1 NULL
Если 'str' имеет значение NULL, возвращается NULL
SELECT REGEXP(NULL, '^billie');
+-------------------------+
| REGEXP(NULL, '^billie') |
+-------------------------+
| NULL |
+-------------------------+
Если 'pattern' имеет значение NULL, возвращается NULL
SELECT REGEXP('billie eillish', NULL);
+--------------------------------+
| REGEXP('billie eillish', NULL) |
+--------------------------------+
| NULL |
+--------------------------------+
Если все параметры имеют значение NULL, возвращается NULL
SELECT REGEXP(NULL, NULL);
+--------------------+
| REGEXP(NULL, NULL) |
+--------------------+
| NULL |
+--------------------+
Если pattern содержит недопустимое регулярное выражение, возникает ошибка:
SELECT REGEXP('Hello, World!', '([a-z');
ERROR 1105 (HY000): errCode = 2, detailMessage = (10.16.10.2)[INTERNAL_ERROR]Invalid regex expression: ([a-z
Для сложных шаблонов требуется расширенный синтаксис. Обычный переход на RE2 не обеспечивает поддержку look-around:
SET enable_hyperscan_fallback = true;
SET enable_extended_regex = true;
SELECT REGEXP('foobar', '(?<=foo)bar');
1
Неконстантные шаблоны также поддерживают расширенный синтаксис (в серии Doris 4.1 начиная с 4.1.5):
CREATE TABLE regexp_patterns (
id INT,
s VARCHAR(32),
p VARCHAR(64)
) DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES ("replication_num" = "1");
INSERT INTO regexp_patterns VALUES
(1, 'foobar', '(?<=foo)bar'),
(2, 'fobar', '(?<=foo)bar'),
(3, 'foo123bar', 'foo(?=123)'),
(4, 'foo124bar', 'foo(?=123)');
SELECT id, REGEXP(s, p) FROM regexp_patterns ORDER BY id;
1 1
2 0
3 1
4 0
Перед выполнением приведённых ниже примеров с обычным синтаксисом восстановите настройку сеанса:
SET enable_extended_regex = false;
Модификаторы шаблона
Сопоставление без учёта регистра: (?i) отключает учёт регистра при сопоставлении
SELECT REGEXP('Hello World', 'hello') AS case_sensitive, REGEXP('Hello World', '(?i)hello') AS case_insensitive;
+----------------+------------------+
| case_sensitive | case_insensitive |
+----------------+------------------+
| 0 | 1 |
+----------------+------------------+
Символ . по умолчанию соответствует символу новой строки; используйте (?-s), чтобы . не соответствовал символу новой строки
SELECT REGEXP('foo\nbar', '^.+$') AS dot_match_nl, REGEXP('foo\nbar', '(?-s)^.+$') AS dot_not_match_nl;
+--------------+------------------+
| dot_match_nl | dot_not_match_nl |
+--------------+------------------+
| 1 | 0 |
+--------------+------------------+
Многострочный режим: (?m) заставляет ^ и $ соответствовать началу и концу каждой строки
SELECT REGEXP('foo\nbar', '^bar') AS single_line, REGEXP('foo\nbar', '(?m)^bar') AS multi_line;
+-------------+------------+
| single_line | multi_line |
+-------------+------------+
| 0 | 1 |
+-------------+------------+
Жадное и нежадное сопоставление: (?U) заставляет квантификаторы захватывать как можно меньше символов
SELECT REGEXP_EXTRACT('aXbXc', '(a.*X)', 1) AS greedy, REGEXP_EXTRACT('aXbXc', '(?U)(a.*X)', 1) AS non_greedy;
+--------+------------+
| greedy | non_greedy |
+--------+------------+
| aXbX | aX |
+--------+------------+