入门指南:全局模式
这篇文章最初发表在malikbrowne.com上。
最近,我的一位同事遇到了麻烦,因为 Jest 无法对他创建的新文件夹运行测试。
经过一番调查,发现 Jest 配置 glob 模式竟然没有包含这整个没有运行的测试文件夹!(太可怕了!)
理解 glob 模式的工作原理对于解决这个问题至关重要,但除了Linux 手册之外,这方面的文档并不多。让我们改变这种状况!
在这篇文章中,我们将回顾通配符的历史,如何使用通配符,并定义通配符匹配的三个主要特征。
那些团状物到底是什么?
通配符(也称为通配符模式)是一种可以将通配符模式扩展为与给定模式匹配的路径名列表的模式。
在早期版本的 Linux 中,命令解释器依赖于一个程序,该程序将这些字符扩展为命令的未加引号的参数:/etc/glob。
后来,这个命令被作为一个库函数提供,现在被包括 shell 在内的大量程序所使用。许多不同的工具和语言都采用了 glob 模式,并对其进行了各自的改进。相关工具和语言的列表相当长:
- Node.js
- 去
- Java
- 哈斯克尔
- Python
- 红宝石
- PHP
现在我们对通配符的历史有了一些了解,接下来让我们来看看它真正有用的部分:通配符匹配。
通配符匹配
如果一个字符串包含以下字符之一,则可以将其视为通配符模式:*,?或[。
星号 (*)
最常见的通配符是星号。这个字符有很多用途,但主要用于匹配任意数量的字符(例如字符串的一部分)。
我见过的星号主要有三种用法:
*- 在 Linux 系统上,它会匹配除斜杠以外的所有字符。在 Windows 系统上,它会避免匹配反斜杠和斜杠。**- 递归匹配当前目录下的零个或多个目录。*(pattern_list)- 仅当上述模式列表中包含零次或一次任何模式时才匹配。
这些用例也可以结合使用!例如,要递归查找所有以 `.markdown` 结尾的 Markdown 文件.md,模式可以是:**/*.md
注意:*.md只会返回当前目录中的值,这就是为什么我们要**/在开头添加内容的原因。
问号(?)
问号通配符通常用于匹配任何单个字符。
例如,假设我们得到一个文件列表:
- 猫.png
- 蝙蝠.png
- 老鼠.png
- 汽车.png
- list.png
- 妈妈.jpg
- cat.jpg
如果要查找_at文件夹中所有包含特定字符的文件,可以使用类似?at这样的模式,这将返回以下结果:
- 猫.png
- 蝙蝠.png
- 老鼠.png
- cat.jpg
注意:这种模式的一个优点是它不区分字符的大小写。我在编写脚本时发现这非常有用,可以用来查找我标记了特定日期的文件。
字符类和范围([)
方括号([、和])可以用来表示一个模式,该模式应该匹配方括号内包含的单个字符。这些被称为字符类。
需要注意的是,括号内的字符串不能为空。这可能会导致对类似这样的奇怪模式产生误解:[][!]
这将匹配字符串的前三个字符,该字符串包含"\[", "\]", 和"!"。
例如,我们继续使用上一个例子中使用的同一个列表:
- 猫.png
- 蝙蝠.png
- 老鼠.png
- 汽车.png
- list.png
- 妈妈.jpg
- cat.jpg
如果您只想匹配此列表中标题大小写正确的文件,可以使用以下模式[CBR]at。
这将返回以下结果:
- 猫.png
- 蝙蝠.png
- 老鼠.png
范围
通配符的一个很棒的功能是范围,范围由两个字符组成,中间用短横线“-”分隔。
例如,该模式[A-E]会匹配任何包含空格的起始字符ABCDE。可以结合使用不同的范围来创建强大的模式。
你可能以前见过一种常见的模式,即匹配字母数字字符串的模式:[A-Za-z0-9 ]
这与以下内容相符:
[A-Z]所有大写字母,从 A 到 Z[a-z]所有小写字母 a 到 z[0-9]0到9之间的所有数字
由于范围也适用于正则表达式,因此它可以用于许多不同领域的数据验证!
互补
值得一提的是,通配符可以与特殊字符配合使用,从而改变模式的运作方式。我看到的两个可以配合使用的特殊字符是感叹号(& !)和反斜杠(& \)。
感叹号可以否定它前面的模式。在我上面分享的字符类示例中,我们使用了以下模式[CBR]at。
如果我们想要明确地筛选出我们想要的结果,我们可以通过在类名前面加上感叹号来否定该模式[!CBR]at。
反斜杠用于移除单个字符'?', '*', 和'[', 的特殊含义,以便它们可以在模式中使用。
为什么 glob 模式有用?
近几个月来,我发现 glob 模式在编写脚本和执行自动化任务时非常有用。能够递归地指定目录树中的特定文件非常宝贵——尤其是在 CI 环境中,你无法控制根目录的名称。
我想指出的一点是,虽然通配符模式与正则表达式模式类似,但它们并不完全相同,主要原因有二:
- 通配符旨在匹配文件名,而不是文本。
- 并非所有约定在它们之间都相同(例如:
*在正则表达式中,0 表示零个或多个相同的值)。
结论
希望这篇关于 glob 模式的概述能帮助你在将来查看各种配置文件时更加清晰易懂。我知道我在阅读 webpack/typescript/jest 配置时也曾为此苦恼,所以如果这篇文章对你有帮助,请在评论区或Twitter 上告诉我!
实用链接/资源
http://www.globtester.com/
https://en.wikipedia.org/wiki/Glob_(programming)
https://commandbox.ortusbooks.com/usage/parameters/globbing-patterns
http://teaching.idallen.com/cst8207/15w/notes/190_glob_patterns.html
http://man7.org/linux/man-pages/man7/glob.7.html