⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
模式匹配

DuckDB 提供了四种独立的模式匹配方法:传统的 SQL LIKE 运算符,较新的 SIMILAR TO 运算符(在 SQL:1999 中添加),GLOB 运算符,以及 POSIX 风格的正则表达式

LIKE

LIKE 表达式在字符串匹配给定模式时返回 true。(正如预期,如果 LIKE 返回 true,则 NOT LIKE 表达式返回 false,反之亦然。等效的表达式是 NOT (string LIKE pattern)。)

如果模式不包含百分号或下划线,则模式仅表示字符串本身;在这种情况下,LIKE 的作用类似于等于运算符。模式中的下划线(_)表示(匹配)任意单个字符;百分号(%)匹配任意零个或多个字符的序列。

LIKE 模式匹配总是覆盖整个字符串。因此,如果需要匹配字符串中任意位置的序列,模式必须以百分号开头和结尾。

示例

SELECT 'abc' LIKE 'abc';    -- true
SELECT 'abc' LIKE 'a%' ;    -- true
SELECT 'abc' LIKE '_b_';    -- true
SELECT 'abc' LIKE 'c';      -- false
SELECT 'abc' LIKE 'c%' ;    -- false
SELECT 'abc' LIKE '%c';     -- true
SELECT 'abc' NOT LIKE '%c'; -- false

可以使用关键字 ILIKE 代替 LIKE,以根据当前活动区域设置使匹配不区分大小写。

SELECT 'abc' ILIKE '%C'; -- true
SELECT 'abc' NOT ILIKE '%C'; -- false

要在字符串中搜索通配符(%_),模式必须使用 ESCAPE 子句和一个转义字符来指示通配符应被视为字面字符而不是通配符。请参阅下面的示例。

此外,函数 like_escape 具有与带有 ESCAPE 子句的 LIKE 表达式相同的功能,但使用的是函数语法。有关详细信息,请参阅文本函数文档

搜索包含“a”后跟一个字面百分号再跟“c”的字符串

SELECT 'a%c' LIKE 'a$%c' ESCAPE '$'; -- true
SELECT 'azc' LIKE 'a$%c' ESCAPE '$'; -- false

不区分大小写的 ILIKE 及 ESCAPE

SELECT 'A%c' ILIKE 'a$%c' ESCAPE '$'; -- true

也有替代字符可以作为关键字代替 LIKE 表达式使用。这些字符增强了 PostgreSQL 的兼容性。

PostgreSQL 风格 LIKE 风格
~~ LIKE
!~~ NOT LIKE
~~* ILIKE
!~~* NOT ILIKE

SIMILAR TO

SIMILAR TO 运算符根据其模式是否匹配给定字符串返回 true 或 false。它类似于 LIKE,不同之处在于它使用正则表达式解释模式。与 LIKE 类似,SIMILAR TO 运算符仅在其模式匹配整个字符串时才成功;这与常见的正则表达式行为不同,后者模式可以匹配字符串的任何部分。

正则表达式是字符序列,是字符串集合(正则集)的简写定义。如果字符串是正则表达式描述的正则集的成员,则称该字符串匹配正则表达式。与 LIKE 类似,模式字符与字符串字符精确匹配,除非它们是正则表达式语言中的特殊字符——但正则表达式使用的特殊字符与 LIKE 不同。

示例

SELECT 'abc' SIMILAR TO 'abc';       -- true
SELECT 'abc' SIMILAR TO 'a';         -- false
SELECT 'abc' SIMILAR TO '.*(b|d).*'; -- true
SELECT 'abc' SIMILAR TO '(b|c).*';   -- false
SELECT 'abc' NOT SIMILAR TO 'abc';   -- false

在 PostgreSQL 中,~ 等效于 SIMILAR TO!~ 等效于 NOT SIMILAR TO。在 DuckDB 中,这些等效关系目前不成立,请参阅PostgreSQL 兼容性页面

Globbing

DuckDB 支持文件名扩展(也称为 globbing)以发现文件。DuckDB 的 glob 语法使用问号(?)通配符匹配任意单个字符,星号(*)匹配零个或多个字符。此外,您可以使用方括号语法([...])匹配方括号内包含的任意单个字符,或方括号指定的字符范围内的字符。感叹号(!)可以在第一个方括号内使用,以搜索不包含在方括号内的字符。要了解更多信息,请访问“glob (programming)”维基百科页面

GLOB

如果字符串匹配 GLOB 模式,则 GLOB 运算符返回 truefalseGLOB 运算符最常用于搜索遵循特定模式的文件名(例如特定文件扩展名)。

示例

SELECT 'best.txt' GLOB '*.txt';            -- true
SELECT 'best.txt' GLOB '????.txt';         -- true
SELECT 'best.txt' GLOB '?.txt';            -- false
SELECT 'best.txt' GLOB '[abc]est.txt';     -- true
SELECT 'best.txt' GLOB '[a-z]est.txt';     -- true

方括号语法区分大小写

SELECT 'Best.txt' GLOB '[a-z]est.txt';     -- false
SELECT 'Best.txt' GLOB '[a-zA-Z]est.txt';  -- true

! 适用于方括号内的所有字符

SELECT 'Best.txt' GLOB '[!a-zA-Z]est.txt'; -- false

要否定 GLOB 运算符,请否定整个表达式

SELECT NOT 'best.txt' GLOB '*.txt';        -- false

三个波浪号(~~~)也可以用来代替 GLOB 关键字。

GLOB 风格 符号风格
GLOB ~~~

用于查找文件名的 Glob 函数

glob 模式匹配语法也可用于使用 glob 表函数搜索文件名。它接受一个参数:要搜索的路径(可能包含 glob 模式)。

搜索当前目录中的所有文件

SELECT * FROM glob('*');
文件
duckdb.exe
test.csv
test.json
test.parquet
test2.csv
test2.parquet
todos.json

Globbing 语义

DuckDB 的 globbing 实现遵循 Python 的 glob 语义,而不是 shell 中使用的 glob。一个显著的区别是 **/ 构造的行为:**/filename 不会返回顶层目录中包含 filename 的文件。例如,如果目录中存在一个 README.md 文件,以下查询可以找到它。

SELECT * FROM glob('README.md');
文件
README.md

然而,以下查询返回空结果。

SELECT * FROM glob('**/README.md');

同时,Bash、Zsh 等的 globbing 使用相同的语法找到了文件。

ls **/README.md
README.md

正则表达式

DuckDB 的正则表达式支持在正则表达式页面上有所说明。DuckDB 支持一些 PostgreSQL 风格的运算符用于正则表达式匹配。

PostgreSQL 风格 等效表达式
~ regexp_full_match
!~ NOT regexp_full_match
~* (不支持)
!~* (不支持)