globbing - 匹配某些文件扩展名但不匹配其他文件扩展名的正确方法
globbing - Correct way to match some files extensions but not others
我在 grunt-aws-s3
任务中编写了下面的代码片段。
var weekCache = 'css|js';
var yearCache = 'jpg|jpeg|png|gif|ico|eot|otf|ttf|woff|woff2';
var prodFiles = [
{expand: true, cwd: 'public', src: ['**/*.!('+weekCache+'|'+yearCache+')'], dest: '/'},
{expand: true, cwd: 'public', src: ['**/*.@('+weekCache+')'], dest: '/', stream: true, params: {CacheControl: 'max-age=604800, public'}}, // enable stream to allow large files
{expand: true, cwd: 'public', src: ['**/*.@('+yearCache+')'], dest: '/', stream: true, params: {CacheControl: 'max-age=31536000, public'}},
];
想法是在 prodFiles
变量中有三个不同的匹配项:
- 匹配除
yearCache
和 weekCache
之外的所有文件
- 匹配所有带有
weekCache
扩展名的文件
- 匹配所有带有
yearCache
扩展名的文件
它或多或少可以工作,我在 public
目录及其子目录中有 63 个文件。然而这些规则匹配了 72 个文件,很明显有些文件至少匹配了两次。
我的通配符有什么问题?
编辑:
使用 node-glob-all
进行的测试表明错误出现在第一个模式中:
$ glob-all '**/*.!(css|js)'
assets/css/style-nuvue6sithwirecbhvw3dkaobiojqvtadsnhguwi7k04xklybw5djl1smadp.min.css
assets/images/favicon.ico
assets/js/jquery.fancybox.js
assets/js/jquery.fancybox-thumbs.js
我原以为这种模式 return 除了 *.js
和 *.css
之外的所有内容。针对其他两个规则进行测试 returned 正确的文件。
$ glob-all '**/*.@(css|js)'
assets/css/style-nuvue6sithwirecbhvw3dkaobiojqvtadsnhguwi7k04xklybw5djl1smadp.min.css
assets/js/jquery.fancybox.js
assets/js/jquery.fancybox-thumbs.js
所以,问题是如何正确否定模式'**/*.!(css|js)'
?
我认为您的问题是您的文件名包含多个点 (.)。
您的模式指定查找包含一定数量的非点字符后跟点字符后跟除 "css" 或 "js".
以外的任何字符的所有文件名
让我们以文件名"jquery.fancybox.js"为例。通过这个文件名,我们发现有一些非点字符,"jquery",后面跟着一个点,“.”,后面跟着的字符不是 "css" 和 不是 "js"、"fancybox.js"。此文件名与模式匹配,因此被返回。
如果上面的文件名是 "fancybox.js",它会匹配一些非点字符,"fancybox",后跟一个点,“.”,但 不是 后跟不是 "css" 和 "js" 的字符。因此这个文件名将无法通过模式匹配并且不会被返回。
我们要做的是在我们的否定模式中指定在我们的“.css”或“.js”扩展名之前可能有更多的非点字符。我们可以使用以下模式来做到这一点:
'**/*.!(*(*.)js|*(*.)css)'
我在 grunt-aws-s3
任务中编写了下面的代码片段。
var weekCache = 'css|js';
var yearCache = 'jpg|jpeg|png|gif|ico|eot|otf|ttf|woff|woff2';
var prodFiles = [
{expand: true, cwd: 'public', src: ['**/*.!('+weekCache+'|'+yearCache+')'], dest: '/'},
{expand: true, cwd: 'public', src: ['**/*.@('+weekCache+')'], dest: '/', stream: true, params: {CacheControl: 'max-age=604800, public'}}, // enable stream to allow large files
{expand: true, cwd: 'public', src: ['**/*.@('+yearCache+')'], dest: '/', stream: true, params: {CacheControl: 'max-age=31536000, public'}},
];
想法是在 prodFiles
变量中有三个不同的匹配项:
- 匹配除
yearCache
和weekCache
之外的所有文件
- 匹配所有带有
weekCache
扩展名的文件
- 匹配所有带有
yearCache
扩展名的文件
它或多或少可以工作,我在 public
目录及其子目录中有 63 个文件。然而这些规则匹配了 72 个文件,很明显有些文件至少匹配了两次。
我的通配符有什么问题?
编辑:
使用 node-glob-all
进行的测试表明错误出现在第一个模式中:
$ glob-all '**/*.!(css|js)'
assets/css/style-nuvue6sithwirecbhvw3dkaobiojqvtadsnhguwi7k04xklybw5djl1smadp.min.css
assets/images/favicon.ico
assets/js/jquery.fancybox.js
assets/js/jquery.fancybox-thumbs.js
我原以为这种模式 return 除了 *.js
和 *.css
之外的所有内容。针对其他两个规则进行测试 returned 正确的文件。
$ glob-all '**/*.@(css|js)'
assets/css/style-nuvue6sithwirecbhvw3dkaobiojqvtadsnhguwi7k04xklybw5djl1smadp.min.css
assets/js/jquery.fancybox.js
assets/js/jquery.fancybox-thumbs.js
所以,问题是如何正确否定模式'**/*.!(css|js)'
?
我认为您的问题是您的文件名包含多个点 (.)。
您的模式指定查找包含一定数量的非点字符后跟点字符后跟除 "css" 或 "js".
以外的任何字符的所有文件名让我们以文件名"jquery.fancybox.js"为例。通过这个文件名,我们发现有一些非点字符,"jquery",后面跟着一个点,“.”,后面跟着的字符不是 "css" 和 不是 "js"、"fancybox.js"。此文件名与模式匹配,因此被返回。
如果上面的文件名是 "fancybox.js",它会匹配一些非点字符,"fancybox",后跟一个点,“.”,但 不是 后跟不是 "css" 和 "js" 的字符。因此这个文件名将无法通过模式匹配并且不会被返回。
我们要做的是在我们的否定模式中指定在我们的“.css”或“.js”扩展名之前可能有更多的非点字符。我们可以使用以下模式来做到这一点:
'**/*.!(*(*.)js|*(*.)css)'