REGEXP_EXTRACT_OR_NULL
Описание
Извлекает из текстовой строки первую подстроку, соответствующую заданному шаблону регулярного выражения, а затем извлекает из неё определённую группу по индексу группы в выражении.
При сопоставлении наборов символов следует использовать стандартные классы символов Utf-8. Это позволяет функциям корректно распознавать и обрабатывать символы разных языков.
Поддерживается начиная с Apache Doris 3.0.2
Если 'pattern' не является допустимым регулярным выражением, возникает ошибка
Классы символов, поддерживаемые по умолчанию: https://github.com/google/re2/wiki/Syntax
Doris поддерживает включение расширенных возможностей регулярных выражений, таких как проверки нулевой ширины с просмотром вперёд и назад, с помощью переменной сеанса enable_extended_regex (по умолчанию false).
Типы сопоставления символов, поддерживаемые при установке переменной сеанса enable_extended_regex в true: https://www.boost.org/doc/libs/latest/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html
Синтаксис
REGEXP_EXTRACT_OR_NULL(<str>, <pattern>, <pos>)
Параметры
| Параметр | Описание |
|---|---|
<str> | Строковый параметр. Задаёт текстовую строку, в которой выполняется поиск совпадений с регулярным выражением. Строка может содержать любую комбинацию символов; функция ищет в ней подстроки, соответствующие |
<pattern> | Строковый параметр. Задаёт целевой шаблон регулярного выражения. Шаблон может включать различные метасимволы регулярных выражений и классы символов, которые точно определяют правила сопоставления подстроки |
<pos> | Целочисленный параметр. Задаёт индекс группы выражения, которую нужно извлечь. Индексация начинается с 1. Если |
Возвращаемое значение
Возвращает значение строкового типа, содержащее фрагмент, соответствующий <pattern>.
Если входной параметр <pos> равен 0, возвращается вся первая совпавшая подстрока.
Если входной параметр <pos> недопустим (отрицателен или превышает число групп выражения), возвращается NULL.
Если совпадение с регулярным выражением не найдено, возвращается NULL.
Если <pos> < 0, возвращается NULL;
Если pos больше длины <str>, возвращается NULL;
Поведение по умолчанию:
| Настройка по умолчанию | Поведение |
|---|---|
. соответствует символу новой строки | . по умолчанию может соответствовать \n (символу новой строки). |
| С учётом регистра | Сопоставление выполняется с учётом регистра. |
^/$ соответствуют границам всей строки | ^ соответствует только началу строки, $ соответствует только её концу, а не началу и концу отдельных строк. |
| Жадные квантификаторы | *, + и другие по умолчанию захватывают как можно больше символов. |
| UTF-8 | Строки обрабатываются как UTF-8. |
Модификаторы шаблона:
Поведение по умолчанию можно изменить, добавив перед pattern префикс (?flags). Можно сочетать несколько модификаторов, например (?im); префикс - отключает соответствующий параметр, например (?-s).
Модификаторы шаблона действуют только при использовании движка регулярных выражений по умолчанию. Если включён enable_extended_regex=true и используются проверки нулевой ширины (например, (?<=...), (?=...)), запрос обрабатывается движком Boost.Regex, и поведение модификаторов может отличаться от ожидаемого. Рекомендуется не сочетать их.
| Флаг | Значение |
|---|---|
(?i) | Сопоставление без учёта регистра |
(?-i) | Сопоставление с учётом регистра (по умолчанию) |
(?s) | . соответствует символу новой строки (включено по умолчанию) |
(?-s) | . не соответствует символу новой строки |
(?m) | Многострочный режим: ^ соответствует началу каждой строки, $ соответствует концу каждой строки |
(?-m) | Однострочный режим: ^/$ соответствуют границам всей строки (по умолчанию) |
(?U) | Нежадные квантификаторы: *, + и другие захватывают как можно меньше символов |
(?-U) | Жадные квантификаторы (по умолчанию): *, + и другие захватывают как можно больше символов |
Пример
Извлечение определённой группы из совпадения. Пояснение: регулярное выражение ([[:lower:]]+)C([[:lower:]]+) ищет последовательности из одной или нескольких строчных букв, разделённые символом 'C'. Группа с индексом 1 соответствует первой последовательности строчных букв, поэтому возвращается 'b'.
SELECT REGEXP_EXTRACT_OR_NULL('123AbCdExCx', '([[:lower:]]+)C([[:lower:]]+)', 1);
+---------------------------------------------------------------------------+
| REGEXP_EXTRACT_OR_NULL('123AbCdExCx', '([[:lower:]]+)C([[:lower:]]+)', 1) |
+---------------------------------------------------------------------------+
| b |
+---------------------------------------------------------------------------+
Возврат всей совпавшей подстроки. Если
SELECT REGEXP_EXTRACT_OR_NULL('123AbCdExCx', '([[:lower:]]+)C([[:lower:]]+)', 0);
+---------------------------------------------------------------------------+
| REGEXP_EXTRACT_OR_NULL('123AbCdExCx', '([[:lower:]]+)C([[:lower:]]+)', 0) |
+---------------------------------------------------------------------------+
| bCd |
+---------------------------------------------------------------------------+
Недопустимый индекс группы. Поскольку шаблон содержит только 2 группы, индекс 5 выходит за допустимые границы, поэтому возвращается NULL.
SELECT REGEXP_EXTRACT_OR_NULL('123AbCdExCx', '([[:lower:]]+)C([[:lower:]]+)', 5);
+---------------------------------------------------------------------------+
| REGEXP_EXTRACT_OR_NULL('123AbCdExCx', '([[:lower:]]+)C([[:lower:]]+)', 5) |
+---------------------------------------------------------------------------+
| NULL |
+---------------------------------------------------------------------------+
Регулярное выражение без совпадений. В строке 'AbCdE' нет фрагмента, полностью соответствующего шаблону
SELECT REGEXP_EXTRACT_OR_NULL('AbCdE', '([[:lower:]]+)C([[:upper:]]+)', 1);
+---------------------------------------------------------------------+
| REGEXP_EXTRACT_OR_NULL('AbCdE', '([[:lower:]]+)C([[:upper:]]+)', 1) |
+---------------------------------------------------------------------+
| NULL |
+---------------------------------------------------------------------+
Сопоставление китайских символов. Шаблон (\p{Han}+)(.+) сначала сопоставляется с одним или несколькими китайскими символами, а затем с любыми оставшимися символами. Группа с индексом 2 соответствует некитайской части строки, следующей за китайскими символами.
select REGEXP_EXTRACT_OR_NULL('这是一段中文 This is a passage in English 1234567', '(\\p{Han}+)(.+)', 2);
+---------------------------------------------------------------------------------------------------------+
| REGEXP_EXTRACT_OR_NULL('这是一段中文 This is a passage in English 1234567', '(\\p{Han}+)(.+)', 2) |
+---------------------------------------------------------------------------------------------------------+
| This is a passage in English 1234567 |
+---------------------------------------------------------------------------------------------------------+
Вставка данных в таблицу и извлечение подстрок
CREATE TABLE test_regexp_extract_or_null (
id INT,
text_column VARCHAR(255),
pattern_column VARCHAR(255),
position_column INT
) PROPERTIES ("replication_num"="1");
INSERT INTO test_regexp_extract_or_null VALUES
(1, 'abc123def', '([a-z]+)([0-9]+)([a-z]+)', 2),
(2, 'Hello World', '([A-Z][a-z]+) ([A-Z][a-z]+)', 0),
(3, '123-456-789', '([0-9]{3})-([0-9]{3})-([0-9]{3})', 3),
(4, 'example@example.com', '([a-z]+)@([a-z]+)\\.([a-z]+)', 1),
(5, '测试文本 test text', '(\\p{Han}+) (.+)', 1);
SELECT id, REGEXP_EXTRACT_OR_NULL(text_column, pattern_column, position_column) AS extracted_result
FROM test_regexp_extract_or_null
ORDER BY id;
+------+-----------------+
| id | extracted_result|
+------+-----------------+
| 1 | 123 |
| 2 | Hello World |
| 3 | 789 |
| 4 | example |
| 5 | 测试文本 |
+------+-----------------+
Пример с эмодзи
SELECT regexp_extract_or_null('😀😊😎', '😀|😊|😎',0);
+------------------------------------------------------------+
| regexp_extract_or_null('😀😊😎', '😀|😊|😎',0) |
+------------------------------------------------------------+
| 😀 |
+------------------------------------------------------------+
Если 'str' равен NULL, возвращается NULL
SELECT REGEXP_EXTRACT_OR_NULL(NULL, '([a-z]+)', 1);
+---------------------------------------------+
| REGEXP_EXTRACT_OR_NULL(NULL, '([a-z]+)', 1) |
+---------------------------------------------+
| NULL |
+---------------------------------------------+
Если 'pattern' равен NULL, возвращается NULL
SELECT REGEXP_EXTRACT_OR_NULL('Hello World', NULL, 1);
+------------------------------------------------+
| REGEXP_EXTRACT_OR_NULL('Hello World', NULL, 1) |
+------------------------------------------------+
| NULL |
+------------------------------------------------+
Если 'pos' равен NULL, возвращается NULL
SELECT REGEXP_EXTRACT_OR_NULL('Hello World', '([a-z]+)', NULL);
+---------------------------------------------------------+
| REGEXP_EXTRACT_OR_NULL('Hello World', '([a-z]+)', NULL) |
+---------------------------------------------------------+
| NULL |
+---------------------------------------------------------+
Если все параметры равны NULL, возвращается NULL;
SELECT REGEXP_EXTRACT_OR_NULL(NULL,NULL,NULL);
+----------------------------------------+
| REGEXP_EXTRACT_OR_NULL(NULL,NULL,NULL) |
+----------------------------------------+
| NULL |
+----------------------------------------+
Если pattern не является допустимым регулярным выражением, возникает ошибка;
mysql> SELECT REGEXP_EXTRACT_OR_NULL('123AbCdExCx', '([[:lower:]]+)C([[]ower:]]+)', 1);
ERROR 1105 (HY000): errCode = 2, detailMessage = (10.16.10.2)[INVALID_ARGUMENT]Could not compile regexp pattern: ([[:lower:]]+)C([[:lower:]+)
Error: missing ]: [[:lower:]+)
Расширенные регулярные выражения
SELECT regexp_extract_or_null('foo123bar', '(?<=foo)(\\d+)(?=bar)', 1);
-- ERROR 1105 (HY000): errCode = 2, detailMessage = (127.0.0.1)[INVALID_ARGUMENT]Invalid regex pattern: (?<=foo)(\d+)(?=bar). Error: invalid perl operator: (?<
SET enable_extended_regex = true;
SELECT regexp_extract_or_null('foo123bar', '(?<=foo)(\\d+)(?=bar)', 1);
+-----------------------------------------------------------------+
| regexp_extract_or_null('foo123bar', '(?<=foo)(\\d+)(?=bar)', 1) |
+-----------------------------------------------------------------+
| 123 |
+-----------------------------------------------------------------+
Модификаторы шаблона
Сопоставление без учёта регистра: (?i) позволяет игнорировать регистр при сопоставлении
SELECT REGEXP_EXTRACT_OR_NULL('Hello World', '(hello)', 1) AS case_sensitive,
REGEXP_EXTRACT_OR_NULL('Hello World', '(?i)(hello)', 1) AS case_insensitive;
+----------------+------------------+
| case_sensitive | case_insensitive |
+----------------+------------------+
| NULL | Hello |
+----------------+------------------+
. по умолчанию соответствует символу новой строки; используйте (?-s), чтобы исключить сопоставление . с символом новой строки
SELECT REGEXP_EXTRACT_OR_NULL('foo\nbar', '^(.+)$', 1) AS dot_match_nl,
REGEXP_EXTRACT_OR_NULL('foo\nbar', '(?-s)^(.+)$', 1) AS dot_not_match_nl;
+--------------+------------------+
| dot_match_nl | dot_not_match_nl |
+--------------+------------------+
| foo
bar | NULL |
+--------------+------------------+
Многострочный режим: (?m) позволяет ^ и $ соответствовать началу и концу каждой строки
SELECT REGEXP_EXTRACT_OR_NULL('foo\nbar', '^(bar)', 1) AS single_line,
REGEXP_EXTRACT_OR_NULL('foo\nbar', '(?m)^(bar)', 1) AS multi_line;
+-------------+------------+
| single_line | multi_line |
+-------------+------------+
| NULL | bar |
+-------------+------------+
Жадное и нежадное сопоставление: (?U) заставляет квантификаторы захватывать как можно меньше символов
SELECT REGEXP_EXTRACT_OR_NULL('aXbXc', '(a.*X)', 1) AS greedy,
REGEXP_EXTRACT_OR_NULL('aXbXc', '(?U)(a.*X)', 1) AS non_greedy;
+--------+------------+
| greedy | non_greedy |
+--------+------------+
| aXbX | aX |
+--------+------------+