DuckDB 提供模式匹配运算符(LIKE
、SIMILAR TO
、GLOB
),并通过函数支持正则表达式。
正则表达式语法
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]) |
查找 string 中 regex 的非重叠出现,并返回 group 的相应值。 |
regexp_full_match(string, regex[, options]) |
如果整个 string 与 regex 匹配,则返回 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])
描述 | 查找 string 中 regex 的非重叠出现,并返回 group 的相应值。可以设置一组可选的options 。 |
示例 | regexp_extract_all('Peter: 33, Paul:14', '(\w+):\s*(\d+)', 2) |
结果 | [33, 14] |
regexp_full_match(string, regex[, options])
描述 | 如果整个 string 与 regex 匹配,则返回 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_list
,regexp_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
。不支持两位或更多位的捕获组。