⌘+k ctrl+k
1.4 (LTS)
搜索快捷键 cmd + k | ctrl + k
模式匹配

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

LIKE

LIKE 表达式在字符串匹配所提供的模式时返回 true。(正如预期,NOT LIKE 表达式在 LIKE 返回 true 时返回 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

使用 ESCAPE 的不区分大小写 ILIKE

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 兼容性页面

Glob 通配

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

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
~* (不支持)
!~* (不支持)
© 2025 DuckDB 基金会,阿姆斯特丹,荷兰
行为准则 商标使用指南