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

REGEXP_EXTRACT_ALL

Описание​

Функция REGEXP_EXTRACT_ALL выполняет сопоставление заданной строки str с регулярным выражением и извлекает все фрагменты, соответствующие первой подгруппе указанного шаблона pattern. Функция возвращает строку, представляющую совпавшую часть шаблона, причём шаблон должен точно соответствовать фрагменту входной строки str. Если совпадений нет или шаблон не содержит подгрупп, возвращается пустая строка.

При сопоставлении наборов символов следует использовать стандартные классы символов Utf-8. Это позволяет функциям корректно распознавать и обрабатывать символы различных языков.

Если '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_ALL(<str>, <pattern>)

Параметры​

ПараметрОписание
<str>Параметр типа String. Задаёт входную строку, для которой выполняется сопоставление с регулярным выражением. Это может быть строковый литерал или ссылка на столбец таблицы, содержащий строковые данные.
<pattern>Этот параметр также имеет тип String. Задаёт шаблон регулярного выражения для сопоставления с входной строкой . Шаблон может включать различные конструкции регулярных выражений, такие как классы символов, квантификаторы и подгруппы.

Возвращаемое значение​

Возвращает NULL, если хотя бы один из аргументов равен NULL.

Функция возвращает строку, представляющую часть входной строки, которая соответствует первой подгруппе указанного регулярного выражения. Тип возвращаемого значения — String. Если совпадений нет или шаблон не содержит подгрупп, возвращается пустая строка.

Вариант функции, возвращающий массив, описан в разделе REGEXP_EXTRACT_ALL_ARRAY.

Поведение по умолчанию:

Настройка по умолчаниюПоведение
. соответствует переводу строки. по умолчанию может соответствовать \n (переводу строки).
С учётом регистраСопоставление выполняется с учётом регистра.
^/$ соответствуют границам всей строки^ соответствует только началу строки, а $ — только её концу, а не началу и концу отдельных строк текста.
Жадные квантификаторы*, + и другие квантификаторы по умолчанию захватывают как можно больше символов.
UTF-8Строки обрабатываются в кодировке UTF-8.

Модификаторы шаблона:

Поведение по умолчанию можно изменить, добавив к pattern префикс (?flags). Несколько модификаторов можно объединить, например (?im); префикс - отключает соответствующий параметр, например (?-s).

Модификаторы шаблона действуют только при использовании стандартного движка регулярных выражений. Если включён enable_extended_regex=true и используются проверки нулевой ширины (например, (?<=...), (?=...)), запрос обрабатывается движком Boost.Regex, и модификаторы могут работать не так, как ожидается. Рекомендуется не сочетать их.

ФлагЗначение
(?i)Сопоставление без учёта регистра
(?-i)Сопоставление с учётом регистра (по умолчанию)
(?s). соответствует переводу строки (включено по умолчанию)
(?-s). не соответствует переводу строки
(?m)Многострочный режим: ^ соответствует началу каждой строки, а $ — концу каждой строки
(?-m)Однострочный режим: ^/$ соответствуют границам всей строки (по умолчанию)
(?U)Нежадные квантификаторы: *, + и другие захватывают как можно меньше символов
(?-U)Жадные квантификаторы (по умолчанию): *, + и другие захватывают как можно больше символов

Пример​

Простое сопоставление строчных букв вокруг 'C'. В этом примере шаблон ([[:lower:]]+)C([[:lower:]]+) соответствует фрагменту строки, в котором за одной или несколькими строчными буквами следует 'C', а затем ещё одна или несколько строчных букв. Первая подгруппа ([[:lower:]]+) перед 'C' соответствует 'b', поэтому результат — ['b'].

SELECT regexp_extract_all('AbCdE', '([[:lower:]]+)C([[:lower:]]+)');
+--------------------------------------------------------------+
| regexp_extract_all('AbCdE', '([[:lower:]]+)C([[:lower:]]+)') |
+--------------------------------------------------------------+
| ['b'] |
+--------------------------------------------------------------+

Несколько совпадений в строке. Здесь шаблон соответствует двум фрагментам строки. В первом совпадении первая подгруппа соответствует 'b', а во втором — 'f'. Поэтому результат — ['b', 'f'].

SELECT regexp_extract_all('AbCdEfCg', '([[:lower:]]+)C([[:lower:]]+)');
+-----------------------------------------------------------------+
| regexp_extract_all('AbCdEfCg', '([[:lower:]]+)C([[:lower:]]+)') |
+-----------------------------------------------------------------+
| ['b','f'] |
+-----------------------------------------------------------------+

Извлечение ключей из пар «ключ — значение». Шаблон соответствует парам «ключ — значение» в строке. Первая подгруппа захватывает ключи, поэтому результат — ['abc', 'def', 'ghi'].

SELECT regexp_extract_all('abc=111, def=222, ghi=333','("[^"]+"|\\w+)=("[^"]+"|\\w+)');
+--------------------------------------------------------------------------------+
| regexp_extract_all('abc=111, def=222, ghi=333', '("[^"]+"|\w+)=("[^"]+"|\w+)') |
+--------------------------------------------------------------------------------+
| ['abc','def','ghi'] |
+--------------------------------------------------------------------------------+

Сопоставление китайских иероглифов. В шаблоне (\p{Han}+)(.+) первая подгруппа (\p{Han}+) соответствует одному или нескольким китайским иероглифам, поэтому результат — ['这是一段中文'].

select regexp_extract_all('这是一段中文 This is a passage in English 1234567', '(\\p{Han}+)(.+)');
+------------------------------------------------------------------------------------------------+
| regexp_extract_all('这是一段中文 This is a passage in English 1234567', '(\p{Han}+)(.+)') |
+------------------------------------------------------------------------------------------------+
| ['这是一段中文'] |
+------------------------------------------------------------------------------------------------+

Вставка данных и использование REGEXP_EXTRACT_ALL


CREATE TABLE test_regexp_extract_all (
id INT,
text_content VARCHAR(255),
pattern VARCHAR(255)
) PROPERTIES ("replication_num"="1");


INSERT INTO test_regexp_extract_all VALUES
(1, 'apple1, banana2, cherry3', '([a-zA-Z]+)\\d'),
(2, 'red#123, blue#456, green#789', '([a-zA-Z]+)#\\d+'),
(3, 'hello@example.com, world@test.net', '([a-zA-Z]+)@');


SELECT id, regexp_extract_all(text_content, pattern) AS extracted_data
FROM test_regexp_extract_all;
+------+----------------------+
| id | extracted_data |
+------+----------------------+
| 1 | ['apple', 'banana', 'cherry'] |
| 2 | ['red', 'blue', 'green'] |
| 3 | ['hello', 'world'] |
+------+----------------------+

Если совпадений нет, возвращается пустая строка

SELECT REGEXP_EXTRACT_ALL('ABC', '(\\d+)');
+-------------------------------------+
| REGEXP_EXTRACT_ALL('ABC', '(\\d+)') |
+-------------------------------------+
| |
+-------------------------------------+

Сопоставление эмодзи

SELECT REGEXP_EXTRACT_ALL('👩‍💻,👨‍🚀', '(💻|🚀)');
+--------------------------------------------------------------+
| REGEXP_EXTRACT_ALL('👩‍💻,👨‍🚀', '(💻|🚀)') |
+--------------------------------------------------------------+
| ['💻','🚀'] |
+--------------------------------------------------------------+

Если 'Str' равен NULL, возвращается NULL

SELECT regexp_extract_all(NULL, '([a-z]+)');
+--------------------------------------+
| regexp_extract_all(NULL, '([a-z]+)') |
+--------------------------------------+
| NULL |
+--------------------------------------+

Если 'pattern' равен NULL, возвращается NULL

SELECT regexp_extract_all('Hello World', NULL);
+-----------------------------------------+
| regexp_extract_all('Hello World', NULL) |
+-----------------------------------------+
| NULL |
+-----------------------------------------+

Если все параметры равны NULL, возвращается NULL

SELECT regexp_extract_all(NULL,NULL);
+-------------------------------+
| regexp_extract_all(NULL,NULL) |
+-------------------------------+
| NULL |
+-------------------------------+

Если pattern не является допустимым регулярным выражением, возникает ошибка;

SELECT regexp_extract_all('hello (world) 123', '([[:alpha:]+');
ERROR 1105 (HY000): errCode = 2, detailMessage = (10.16.10.2)[INVALID_ARGUMENT]Could not compile regexp pattern: ([[:alpha:]+
Error: missing ]: [[:alpha:]+

Расширенные регулярные выражения

SELECT REGEXP_EXTRACT_ALL('ID:AA-1,ID:BB-2,ID:CC-3', '(?<=ID:)([A-Z]{2}-\\d)');
ERROR 1105 (HY000): errCode = 2, detailMessage = (127.0.0.1)[INVALID_ARGUMENT]Invalid regex pattern: (?<=ID:)([A-Z]{2}-\d). Error: invalid perl operator: (?<
SET enable_extended_regex = true;
SELECT REGEXP_EXTRACT_ALL('ID:AA-1,ID:BB-2,ID:CC-3', '(?<=ID:)([A-Z]{2}-\\d)');
+-------------------------------------------------------------------------+
| REGEXP_EXTRACT_ALL('ID:AA-1,ID:BB-2,ID:CC-3', '(?<=ID:)([A-Z]{2}-\\d)') |
+-------------------------------------------------------------------------+
| ['AA-1','BB-2','CC-3'] |
+-------------------------------------------------------------------------+

Модификаторы шаблона

Сопоставление без учёта регистра: (?i) позволяет игнорировать регистр при сопоставлении

SELECT REGEXP_EXTRACT_ALL('Hello hello HELLO', '(hello)') AS case_sensitive,
REGEXP_EXTRACT_ALL('Hello hello HELLO', '(?i)(hello)') AS case_insensitive;
+----------------+---------------------------+
| case_sensitive | case_insensitive |
+----------------+---------------------------+
| ['hello'] | ['Hello','hello','HELLO'] |
+----------------+---------------------------+

Многострочный режим: (?m) позволяет ^ и $ соответствовать началу и концу каждой строки

SELECT REGEXP_EXTRACT_ALL('foo\nbar\nbaz', '^([a-z]+)') AS single_line,
REGEXP_EXTRACT_ALL('foo\nbar\nbaz', '(?m)^([a-z]+)') AS multi_line;
+-------------+---------------------+
| single_line | multi_line |
+-------------+---------------------+
| ['foo'] | ['foo','bar','baz'] |
+-------------+---------------------+

Жадные и нежадные квантификаторы: (?U) заставляет квантификаторы захватывать как можно меньше символов

SELECT REGEXP_EXTRACT_ALL('aXbXcXd', '(a.*X)') AS greedy,
REGEXP_EXTRACT_ALL('aXbXcXd', '(?U)(a.*X)') AS non_greedy;
+----------+------------+
| greedy | non_greedy |
+----------+------------+
| ['aXbXcX'] | ['aX'] |
+----------+------------+