← glob · 文件路径的迷你匹配语言 / brace 多选一与 extglob 方言差异 待审核 3 / 6
03 · {} 与 extglob

brace 多选一与 extglob 方言差异

「js 和 ts 都要」有两种写法,机制完全不同:{js,ts} 在 bash 里是 brace expansion——匹配开始之前先把一条 pattern 文本展开成多条;@(js|ts)extglob——匹配进行当中在段内做选择/重复。本仓库实现 @vega/parsing/glob 收录了 {a,b}(转译成 regex 的 (?:a|b),不做文本预展开),未收录 extglob 与 {1..3} 数字区间——后两者在本页只做语法对照,不提供交互 demo。

1 · {a,b}:一条 pattern,多选一

规则三条:逗号分选项 {a,b};可嵌套——jp{,e}g 里那个空选项展开出 jpg / jpeg;可以包住 /——{src,test}/**/*.ts 的每个分支都是一条完整的多段 pattern。多个组相邻就是笛卡尔积,条数相乘(最后一个预设 2×2×2 = 8 条)——这也是它的风险:分支数随组数指数增长,在大目录上要克制。

两种实现机制,同一个匹配结果。bash 把 brace 当文本预处理:先展开成 N 条 pattern 再逐条匹配(所以 bash 里 echo {a,b}.txt 不需要任何文件存在也会输出两个名字)。本仓库实现走另一条路:{a,b} 作为 AST 节点直接转译成 regex 的分支 (?:a|b),一条 regex 一次匹配完成——上面第二块输出就是证据。对「path 是否命中」这个判定,两种机制等价。

**{1..3} 数字区间:本仓库实现未收录。**bash 与 minimatch 支持 file{1..5}.txt 这种区间展开(铺成 file1.txtfile5.txt);@vega/parsing/glob 未收录这个语法,{1..5} 会被当成字面量单选项(花括号里没有顶层逗号)。需要同样效果时写显式列表 file{1,2,3,4,5}.txt 或字符类 file[1-5].txt

2 · extglob:段内的「带量词分组」(bash / minimatch 扩展,本仓库实现未收录)

bash 系还有一组「分组 + 量词」语法,量词写在分组前面,统称 extglob。它是 bash 的可选特性(需 shopt -s extglob),minimatch / node-glob 默认支持,VS Code 的 glob 与本仓库实现都不支持。语法对照如下(仅供阅读,本页不提供交互 demo):

最实用的是 !(...) 反选:!(*.min).js 读作「js 文件,但 .js 前面那截不能匹配 *.min」——一条 pattern 就排除了压缩产物。config?(.local).json 则用 ?() 同时覆盖「带与不带 .local」两种文件名。在不支持 extglob 的环境里,反选要改用工具自身的排除机制(如 node-glob 的 ignore 选项,见 04 页),多选一优先写三家通用的 {}

**支持度差异比语法本身更重要:**extglob 是 bash 系特性,跨工具复用的 pattern 应避开它;{} 在 bash / node-glob / VS Code 都可用(gitignore 不认)。完整对照见 06 速查页