メインコンテンツまでスキップ
に最終更新

REGEXP_EXTRACT

説明​

この関数は、指定した文字列 STR に正規表現を適用し、指定したパターンに一致する POS 番目の部分を抽出します。一致結果を返すには、パターンが STR の一部と正確に一致する必要があります。

一致する部分が見つからない場合は、空文字列を返します。 文字集合を照合する際は、UTF-8 標準の文字クラスを使用してください。これにより、さまざまな言語の文字を正しく識別して処理できます。

str パラメータは文字列型で、正規表現による照合の対象となる文字列を表します。 pattern パラメータは文字列型で、照合する正規表現パターンを表します。 pos パラメータは整数型で、正規表現の一致を検索し始める文字列内の位置を指定します。位置は 1 から始まり、このパラメータは必須です。

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(<str>, <pattern>, <pos>)

パラメータ​

パラメータ説明
<str>正規表現で照合する列。文字列型です。
<pattern>照合する正規表現パターン。文字列型です。
<pos>正規表現の一致を検索し始める文字列内の位置を指定するパラメータ。文字列内の文字位置を表す整数値で、1 から始まります。pos の指定は必須です。

戻り値​

パターンに一致する部分を VARCHAR 型で返します。一致する部分が見つからない場合は、空文字列を返します。いずれかの引数が NULL の場合は、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、さらに一文字以上の小文字が続く部分に一致します。C より前の最初のキャプチャグループ ([[:lower:]]+) は b に一致するため、結果は b です。

mysql> SELECT regexp_extract('AbCdE', '([[:lower:]]+)C([[:lower:]]+)', 1);
+-------------------------------------------------------------+
| regexp_extract('AbCdE', '([[:lower:]]+)C([[:lower:]]+)', 1) |
+-------------------------------------------------------------+
| b |
+-------------------------------------------------------------+

二番目の一致部分を抽出します。ここでは、C より後の二番目のキャプチャグループ ([[:lower:]]+) が d に一致するため、結果は d です。

mysql> SELECT regexp_extract('AbCdE', '([[:lower:]]+)C([[:lower:]]+)', 2);
+-------------------------------------------------------------+
| regexp_extract('AbCdE', '([[:lower:]]+)C([[:lower:]]+)', 2) |
+-------------------------------------------------------------+
| d |
+-------------------------------------------------------------+

中国語の文字に一致させます。パターン (\p{Han}+)(.+) は、まず一文字以上の中国語の文字(\p{Han}+)に一致し、続いて文字列の残りの部分((.+))に一致します。二番目のキャプチャグループは中国語以外の部分に一致するため、結果は 'This is a passage in English 1234567' です。

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

値をテーブルに挿入して照合します。この例では、テーブルにデータを挿入し、保存されたパターンと位置に基づいて、REGEXP_EXTRACT 関数で保存された文字列から一致部分を抽出します。


CREATE TABLE test_table_for_regexp_extract (
id INT,
text_data VARCHAR(500),
pattern VARCHAR(100),
pos INT
) PROPERTIES ("replication_num"="1");

INSERT INTO test_table_for_regexp_extract VALUES
(1, 'AbCdE', '([[:lower:]]+)C([[:lower:]]+)', 1),
(2, 'AbCdE', '([[:lower:]]+)C([[:lower:]]+)', 2),
(3, '这是一段中文 This is a passage in English 1234567', '(\\p{Han}+)(.+)', 2);

SELECT id, regexp_extract(text_data, pattern, pos) as extract_result FROM test_table_for_regexp_extract ORDER BY id;

+------+----------------+
| id | extract_result |
+------+----------------+
| 1 | b |
| 2 | d |
| 3 | This is a passage in English 1234567 |
+------+----------------+

一致する部分がないパターンを試します。パターン ([[:digit:]]+)(一桁以上の数字)は文字列 'AbCdE' のどの部分にも一致しないため、空文字列が返されます。

SELECT regexp_extract('AbCdE', '([[:digit:]]+)', 1);
+------------------------------------------------+
| regexp_extract('AbCdE', '([[:digit:]]+)', 1) |
+------------------------------------------------+
| |
+------------------------------------------------+

絵文字のテストケース

SELECT regexp_extract('Text 😊 More 😀', '😊|😀',0);

+------------------------------------------------------+
| regexp_extract('Text 😊 More 😀', '😊|😀',0) |
+------------------------------------------------------+
| 😊 |
+------------------------------------------------------+

'str' が NULL の場合は NULL を返します。

mysql> SELECT REGEXP_EXTRACT(NULL, '([a-z]+)', 1);
+-------------------------------------+
| REGEXP_EXTRACT(NULL, '([a-z]+)', 1) |
+-------------------------------------+
| NULL |
+-------------------------------------+

'pattern' が NULL の場合は NULL を返します。

mysql> SELECT REGEXP_EXTRACT('Hello World', NULL, 1);
+----------------------------------------+
| REGEXP_EXTRACT('Hello World', NULL, 1) |
+----------------------------------------+
| NULL |
+----------------------------------------+

'pos' が NULL の場合は NULL を返します。

mysql> SELECT REGEXP_EXTRACT('Hello World', '([a-z]+)', NULL);
+-------------------------------------------------+
| REGEXP_EXTRACT('Hello World', '([a-z]+)', NULL) |
+-------------------------------------------------+
| NULL |
+-------------------------------------------------+

すべてのパラメータが NULL の場合は NULL を返します。

mysql> SELECT REGEXP_EXTRACT(NULL, NULL, NULL);
+----------------------------------+
| REGEXP_EXTRACT(NULL, NULL, NULL) |
+----------------------------------+
| NULL |
+----------------------------------+

pattern が有効な正規表現でない場合は、エラーになります。

SELECT regexp_extract('AbCdE', '([[:digit:]]+', 1);
ERROR 1105 (HY000): errCode = 2, detailMessage = (10.16.10.2)[INVALID_ARGUMENT]Could not compile regexp pattern: ([[:digit:]]+
Error: missing ): ([[:digit:]]+

高度な正規表現

SELECT regexp_extract('foo123bar456baz', '(?<=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('foo123bar456baz', '(?<=foo)(\\d+)(?=bar)', 1);
+---------------------------------------------------------------+
| regexp_extract('foo123bar456baz', '(?<=foo)(\\d+)(?=bar)', 1) |
+---------------------------------------------------------------+
| 123 |
+---------------------------------------------------------------+

パターン修飾子

大文字と小文字を区別しない照合: (?i) を指定すると、大文字と小文字を区別せずに照合します。

SELECT REGEXP_EXTRACT('Hello World', '(hello)', 1) AS case_sensitive,
REGEXP_EXTRACT('Hello World', '(?i)(hello)', 1) AS case_insensitive;
+----------------+------------------+
| case_sensitive | case_insensitive |
+----------------+------------------+
| | Hello |
+----------------+------------------+

デフォルトでは . は改行に一致します。(?-s) を使用すると、. が改行に一致しなくなります。

SELECT REGEXP_EXTRACT('foo\nbar', '^(.+)$', 1) AS dot_match_nl,
REGEXP_EXTRACT('foo\nbar', '(?-s)^(.+)$', 1) AS dot_not_match_nl;
+--------------+------------------+
| dot_match_nl | dot_not_match_nl |
+--------------+------------------+
| foo
bar | |
+--------------+------------------+

複数行モード: (?m) を指定すると、^ と $ は各行の先頭と末尾に一致します。

SELECT REGEXP_EXTRACT('foo\nbar', '^(bar)', 1) AS single_line,
REGEXP_EXTRACT('foo\nbar', '(?m)^(bar)', 1) AS multi_line;
+-------------+------------+
| single_line | multi_line |
+-------------+------------+
| | bar |
+-------------+------------+

貪欲な一致と非貪欲な一致: (?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 |
+--------+------------+