Glob 模式
Glob 模式的通配符、匹配规则与在 Hugo 中的用法。
什么是 Glob 模式
Glob 模式(glob pattern)是用一组通配符来匹配多个值的写法。它把多个目标压缩成一个简短的表达式,因此适合对成组的数据或配置做批量处理,例如一次匹配某个目录下的全部图片,或一次匹配若干种文件扩展名。
下表列出 Hugo 支持的 glob 语法与匹配行为。每一行给出一种匹配类型、所用模式、用于测试的字符串,以及在测试字符串上求值得到的布尔结果。
| 匹配类型 | Glob 模式 | 测试字符串 | 是否匹配 |
|---|---|---|---|
| 简单通配 | images/*.jpg |
images/a.jpg |
true |
| 字面量匹配 | images/a\*.jpg |
images/a*.jpg |
true |
| 单层通配 | images/*/a.jpg |
images/foo/a.jpg |
true |
| 单层通配 | images/*/a.jpg |
images/foo/bar/a.jpg |
false |
| 多层通配 | images/**/a.jpg |
images/foo/bar/a.jpg |
true |
| 多层通配 | images/**/a.jpg |
images/a.jpg |
false |
| 单个字符 | image.??? |
image.jpg |
true |
| 单个字符 | image.??? |
image.avif |
false |
| 定界符排除 | ?at |
f/at |
false |
| 字符列表 | images/a.[jp]pg |
images/a.jpg |
true |
| 取反列表 | images/a.[!p]pg |
images/a.jpg |
true |
| 字符范围 | images/a-[a-c].jpg |
images/a-b.jpg |
true |
| 字符范围 | images/a-[a-c].jpg |
images/a-z.jpg |
false |
| 取反范围 | images/a-[!a-c].jpg |
images/a-z.jpg |
true |
| 模式备选 | images/*.{jpg,png} |
images/logo.png |
true |
| 不匹配 | images/*.{jpg,png} |
images/logo.webp |
false |
匹配规则
匹配逻辑遵循以下规则。
- 标准通配符(
*)匹配任意字符,但不匹配定界符。 - 超级通配符(
**)匹配包括定界符在内的任意字符;但当它位于两个定界符之间时,至少需要一个中间字符,也就是说它不匹配零层目录。 - 单个字符(
?)恰好匹配一个字符,且不匹配定界符。 - 取反(
!)用在方括号内部时,匹配除列表或范围中指定的字符之外的任意字符。 - 字符范围(
[a-z])匹配指定范围内的任意单个字符。
定界符
定界符是斜杠(/);只有在匹配语义化版本(semantic version)字符串时,定界符才是点号(.)。
转义
模式中的反斜杠用来取消下一个字符的特殊含义。上表里 images/a\*.jpg 能匹配 images/a*.jpg,正是因为其中的 * 被转义成了字面量,不再充当通配符。因此当文件名本身含有 *、?、[、]、{、} 这类字符时,需要逐个转义后才能写成模式。
把模式写进配置文件时还要注意引号:TOML 的基本字符串(双引号)本身会把反斜杠当作转义字符,所以上游示例改用单引号的字面量字符串,例如 files = ['! docs/*']。
在 Hugo 中的用法
Glob 模式出现在多个函数与配置项中,匹配的对象各不相同。
资源查找。 函数 resources.GetMatch 与 resources.Match 用来查找全局资源,方法 Resources.GetMatch 与 Resources.Match 用来查找页面资源。这两组都使用不区分大小写的 glob 模式。
{{ with resources.GetMatch "images/*.jpg" }}
<img src="{{ .RelPermalink }}" alt="">
{{ end }}{{ with .Resources.GetMatch "cover.*" }}
<img src="{{ .RelPermalink }}" alt="">
{{ end }}页面资源元数据。 页面前置字段 resources 数组中的 pattern 是 glob 模式,按相对于页面包的文件路径匹配一个或多个页面资源,匹配同样不区分大小写;匹配到多个资源时,同一份元数据会应用到每一个资源。
页面匹配器。 级联的 target、构建选项 _build 以及分段(segments)的筛选条件都使用页面匹配器,其中的 environment、kind、path 都是 glob 模式,例如 {staging,production}、{taxonomy,term}、{/books,/books/**}。
模块挂载。 module.mounts 的 files 接受一个 glob 切片(glob slice),用来指定包含或排除哪些文件。切片中的模式以 ! 加一个空格开头时表示取反;一旦取反项命中,切片中其余模式就不再参与求值,因此取反适合做早期、粗粒度的排除。
[module]
[[module.mounts]]
source = 'content'
target = 'content'
files = ['! docs/*']部署目标。 deployment.targets 的 include 与 exclude 都是 glob 模式:本地文件未通过这两项过滤时不会上传,远端文件未通过这两项过滤时不会被删除。
HTTP 缓存。 HTTPCache 的 includes、excludes,以及轮询所用的 includes、excludes,都是 glob 模式切片。这些模式针对完整的远程 URL 匹配,并以 / 作为路径分隔符,例如 **.json。
开发服务器。 [[server.redirects]] 的 from 是 glob 模式,fromHeaders 的值也用 glob 模式匹配请求头;若 from 与 fromRe 同时设置,请求的 URL 必须同时匹配两者。
命令行。 全局选项 --ignoreVendorPaths 用一个 glob 模式指定哪些模块路径忽略其中的 _vendor;hugo mod clean 的 --pattern 用 glob 模式挑选要清理的模块路径。
hugo mod clean --pattern "**hugo*"注意事项与差异
- 并非所有「模式」都是 glob。 部署 matcher 的
pattern与服务器重定向的fromRe都是正则表达式,不能套用上面的通配符表。 - 大小写。 资源查找与页面资源元数据的
pattern采用不区分大小写的匹配;上游文档未对其它位置作此说明,不要默认它们也不区分大小写。 **不匹配零层目录。images/**/a.jpg匹配images/foo/bar/a.jpg,但不匹配images/a.jpg。- 定界符有例外。 只有匹配语义化版本字符串时,定界符才是点号(
.),其余场合都是斜杠(/)。
某个位置支持何种模式、匹配范围又是什么,最终以该处的说明为准,例如配置 Hugo、Hugo 模块与内容管理中的对应页面。