如何编写一个匹配不在目录

时间:2018-01-19 21:42:02

标签: javascript node.js glob minimatch

我的情况是我需要一个glob模式(使用minimatch)来匹配不在某个目录中的所有JavaScript文件。不幸的是,我正在使用另一个不暴露任何选项的工具(比如ignore glob),所以它必须是一个单独的glob来完成这项工作。

Here's what I have so far

screenshot of globtester

示例输入(匹配顶部,但 匹配底部):

docs/foo/thing.js
docs/thing.js
client/docs/foo/thing.js
client/docs/thing.js

src/foo/thing.js
src/thing.js
docs-src/foo/thing.js
docs-src/thing.js
client/docs-src/foo/thing.js
client/docs-src/thing.js

到目前为止,这就是我对glob模式所拥有的:

**/!(docs)/*.js

这样我就匹配docs/foo/thing.jsclient/docs/foo/thing.js而不匹配docs-src/thing.jsclient/docs-src/thing.js。如果我将我的glob切换到**/!(docs)/**/*.js,那么我可以匹配client/docs-src/thing.js,但我也匹配client/docs/thing.js

我不确定这是可能的,所以我可能需要为我的问题找到另一个解决方案: - /

2 个答案:

答案 0 :(得分:4)

我认为您可能遇到minimatch(或fnmatch(3)的任何实现)和globstar的限制。或许值得注意的是,我所知道的fnmatch的C实现实际上实现了实现了globstar,但是由于fnmatch impls(包括minimatch)服务于它们的globbers的利益,这可能会有所不同。

当你用作glob时,你认为应该工作的glob确实有用。

$ find . -type f
./docs/foo/thing.js
./docs/thing.js
./docs/nope.txt
./docs-src/foo/thing.js
./docs-src/thing.js
./x.sh
./client/docs/foo/thing.js
./client/docs/thing.js
./client/docs/nope.txt
./client/docs-src/foo/thing.js
./client/docs-src/thing.js
./client/docs-src/nope.txt
./client/nope.txt
./src/foo/thing.js
./src/thing.js

$ for i in ./!(docs)/**/*.js; do echo $i; done
./client/docs-src/foo/thing.js
./client/docs-src/thing.js
./client/docs/foo/thing.js
./client/docs/thing.js
./docs-src/foo/thing.js
./docs-src/thing.js
./src/foo/thing.js
./src/thing.js

$ node -p 'require("glob").sync("./!(docs)/**/*.js")'
[ './client/docs-src/foo/thing.js',
  './client/docs-src/thing.js',
  './client/docs/foo/thing.js',
  './client/docs/thing.js',
  './docs-src/foo/thing.js',
  './docs-src/thing.js',
  './src/foo/thing.js',
  './src/thing.js' ]
编辑:哦,我明白了,你想只匹配路径中没有任何 docs路径部分 的任何文件夹深度的东西。不,这不可能以支持任意深度的方式进行,如glob或minimatch模式。您必须使用排除,或构建一个类似于:{!(docs),!(docs)/!(docs),!(docs)/!(docs)/!(docs),!(docs)/!(docs)/!(docs)/!(docs)}/*.js

的glob

否则,x/docs/y/z.js之类的路径会与**/!(docs)/**/*.js匹配,说第一个**不匹配,!(docs)匹配x,下一个**docs/y匹配,然后*.jsz.js匹配。

答案 1 :(得分:1)

我离得更近了,有以下几点:

**/?(docs*[a-zA-Z0-9]|!(docs))/*.js

globtester

仍然试图让它在任意深度上工作。