⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
正则表达式

DuckDB 提供模式匹配运算符LIKESIMILAR TOGLOB),并通过函数支持正则表达式。

正则表达式语法

DuckDB 使用 RE2 库作为其正则表达式引擎。有关正则表达式语法,请参阅 RE2 文档

函数

所有函数都接受一组可选的选项

名称 描述
regexp_extract(string, pattern[, group = 0][, options]) 如果 string 包含正则表达式 pattern,则返回由可选参数 group 指定的捕获组;否则,返回空字符串。group 必须是一个常量值。如果没有给出 group,则默认为 0。可以设置一组可选的options
regexp_extract(string, pattern, name_list[, options]) 如果 string 包含正则表达式 pattern,则将捕获组作为结构体返回,其中包含来自 name_list 的相应名称;否则,返回一个具有相同键和空字符串作为值的结构体。
regexp_extract_all(string, regex[, group = 0][, options]) 查找 stringregex 的非重叠出现,并返回 group 的相应值。
regexp_full_match(string, regex[, options]) 如果整个 stringregex 匹配,则返回 true
regexp_matches(string, pattern[, options]) 如果 string 包含正则表达式 pattern,则返回 true,否则返回 false
regexp_replace(string, pattern, replacement[, options]) 如果 string 包含正则表达式 pattern,则将匹配部分替换为 replacement。默认情况下,只替换第一次出现。可以设置一组可选的options,包括全局标志 g
regexp_split_to_array(string, regex[, options]) string_split_regex 的别名。沿 regex 分割 string
regexp_split_to_table(string, regex[, options]) 沿 regex 分割 string 并为每个部分返回一行。

regexp_extract(string, pattern[, group = 0][, options])

描述 如果 string 包含正则表达式 pattern,则返回由可选参数 group 指定的捕获组;否则,返回空字符串。group 必须是一个常量值。如果没有给出 group,则默认为 0。可以设置一组可选的options
示例 regexp_extract('abc', '([a-z])(b)', 1)
结果 a

regexp_extract(string, pattern, name_list[, options])

描述 如果 string 包含正则表达式 pattern,则将捕获组作为结构体返回,其中包含来自 name_list 的相应名称;否则,返回一个具有相同键和空字符串作为值的结构体。可以设置一组可选的options
示例 regexp_extract('2023-04-15', '(\d+)-(\d+)-(\d+)', ['y', 'm', 'd'])
结果 {'y':'2023', 'm':'04', 'd':'15'}

regexp_extract_all(string, regex[, group = 0][, options])

描述 查找 stringregex 的非重叠出现,并返回 group 的相应值。可以设置一组可选的options
示例 regexp_extract_all('Peter: 33, Paul:14', '(\w+):\s*(\d+)', 2)
结果 [33, 14]

regexp_full_match(string, regex[, options])

描述 如果整个 stringregex 匹配,则返回 true。可以设置一组可选的options
示例 regexp_full_match('anabanana', '(an)*')
结果 false

regexp_matches(string, pattern[, options])

描述 如果 string 包含正则表达式 pattern,则返回 true,否则返回 false。可以设置一组可选的options
示例 regexp_matches('anabanana', '(an)*')
结果 true

regexp_replace(string, pattern, replacement[, options])

描述 如果 string 包含正则表达式 pattern,则将匹配部分替换为 replacement。默认情况下,只替换第一次出现。可以设置一组可选的options,包括全局标志 g
示例 regexp_replace('hello', '[lo]', '-')
结果 he-lo

regexp_split_to_array(string, regex[, options])

描述 string_split_regex 的别名。沿 regex 分割 string。可以设置一组可选的options
示例 regexp_split_to_array('hello world; 42', ';? ')
结果 ['hello', 'world', '42']

regexp_split_to_table(string, regex[, options])

描述 沿 regex 分割 string 并为每个部分返回一行。可以设置一组可选的options
示例 regexp_split_to_table('hello world; 42', ';? ')
结果 三行数据:'hello''world''42'

函数 regexp_matches 类似于 SIMILAR TO 运算符,但它不要求整个字符串都匹配。相反,如果字符串仅包含模式,则 regexp_matches 返回 true(除非使用特殊标记 ^$ 将正则表达式锚定到字符串的开头和结尾)。下面是一些示例:

SELECT regexp_matches('abc', 'abc');       -- true
SELECT regexp_matches('abc', '^abc$');     -- true
SELECT regexp_matches('abc', 'a');         -- true
SELECT regexp_matches('abc', '^a$');       -- false
SELECT regexp_matches('abc', '.*(b|d).*'); -- true
SELECT regexp_matches('abc', '(b|c).*');   -- true
SELECT regexp_matches('abc', '^(b|c).*');  -- false
SELECT regexp_matches('abc', '(?i)A');     -- true
SELECT regexp_matches('abc', 'A', 'i');    -- true

正则表达式函数选项

正则表达式函数支持以下 options

选项 描述
'c' 区分大小写匹配
'i' 不区分大小写匹配
'l' 匹配字面值而非正则表达式标记
'm', 'n', 'p' 换行符敏感匹配
'g' 全局替换,仅适用于 regexp_replace
's' 非换行符敏感匹配

例如

SELECT regexp_matches('abcd', 'ABC', 'c'); -- false
SELECT regexp_matches('abcd', 'ABC', 'i'); -- true
SELECT regexp_matches('ab^/$cd', '^/$', 'l'); -- true
SELECT regexp_matches(E'hello\nworld', 'hello.world', 'p'); -- false
SELECT regexp_matches(E'hello\nworld', 'hello.world', 's'); -- true

使用 regexp_matches

在可能的情况下,regexp_matches 运算符将被优化为 LIKE 运算符。为了获得最佳性能,如果适用,应传递 'c' 选项(区分大小写匹配)。请注意,默认情况下,RE2不会将 . 字符匹配到换行符。

原始表达式 优化等价表达式
regexp_matches('hello world', '^hello', 'c') prefix('hello world', 'hello')
regexp_matches('hello world', 'world$', 'c') suffix('hello world', 'world')
regexp_matches('hello world', 'hello.world', 'c') LIKE 'hello_world'
regexp_matches('hello world', 'he.*rld', 'c') LIKE '%he%rld'

使用 regexp_replace

函数 regexp_replace 可用于将字符串中与正则表达式模式匹配的部分替换为替换字符串。可以使用符号 \d(其中 d 是指示组的数字)在替换字符串中引用正则表达式中捕获的组。请注意,默认情况下,regexp_replace 只替换正则表达式的第一次出现。要替换所有出现,请使用全局替换(g)标志。

使用 regexp_replace 的一些示例

SELECT regexp_replace('abc', '(b|c)', 'X');        -- aXc
SELECT regexp_replace('abc', '(b|c)', 'X', 'g');   -- aXX
SELECT regexp_replace('abc', '(b|c)', '\1\1\1\1'); -- abbbbc
SELECT regexp_replace('abc', '(.*)c', '\1e');      -- abe
SELECT regexp_replace('abc', '(a)(b)', '\2\1');    -- bac

使用 regexp_extract

函数 regexp_extract 用于提取字符串中与正则表达式模式匹配的部分。可以使用 group 参数提取模式中特定的捕获组。如果未指定 group,则默认为 0,提取与整个模式的第一次匹配。

SELECT regexp_extract('abc', '.b.');           -- abc
SELECT regexp_extract('abc', '.b.', 0);        -- abc
SELECT regexp_extract('abc', '.b.', 1);        -- (empty)
SELECT regexp_extract('abc', '([a-z])(b)', 1); -- a
SELECT regexp_extract('abc', '([a-z])(b)', 2); -- b

函数 regexp_extract 还支持 name_list 参数,它是一个字符串 LIST。使用 name_listregexp_extract 将返回相应的捕获组作为 STRUCT 的字段。

SELECT regexp_extract('2023-04-15', '(\d+)-(\d+)-(\d+)', ['y', 'm', 'd']);
{'y': 2023, 'm': 04, 'd': 15}
SELECT regexp_extract('2023-04-15 07:59:56', '^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)', ['y', 'm', 'd']);
{'y': 2023, 'm': 04, 'd': 15}
SELECT regexp_extract('duckdb_0_7_1', '^(\w+)_(\d+)_(\d+)', ['tool', 'major', 'minor', 'fix']);
Binder Error:
Not enough group names in regexp_extract

如果列名的数量少于捕获组的数量,则只返回第一个组。如果列名的数量更多,则会生成错误。

限制

正则表达式仅支持 9 个捕获组:\1\2\3、…、\9。不支持两位或更多位的捕获组。