Перейти к содержимому
Последнее обновление

REGEXP

Описание​

Проверяет строку <str> на соответствие регулярному выражению и возвращает true при совпадении и false в противном случае. Шаблон не обязан совпадать со всей строкой; для полного совпадения используйте ^ и $. Возвращает NULL, если хотя бы один аргумент равен NULL, и сообщает об ошибке, если шаблон некорректен. Строки обрабатываются в кодировке UTF-8; для сопоставления с категориями символов Unicode используйте классы символов, например \p{Han}.

Для обычных шаблонов см. синтаксис RE2.

Движки сопоставления и переменные сеанса​

При обычном сопоставлении с помощью LIKE и REGEXP может использоваться ускорение Hyperscan. Следующие переменные сеанса управляют переходом на другой движок:

Переменная сеансаПо умолчаниюПоведение
enable_hyperscan_fallbacktrueПоддерживается в серии Doris 4.1 начиная с 4.1.5. Позволяет пути выполнения, на котором действительно используется компиляция в Hyperscan, переходить на RE2 при ошибке компиляции или невозможности выделить рабочую память для сопоставления. При false возвращается соответствующая ошибка. На оптимизации простых шаблонов и пути выполнения, напрямую использующие RE2, не влияет.
enable_extended_regexfalseРазрешает 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 |
+--------+------------+