微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Javascript-NodeJS&Glob:必须用单个字符串排除任何数量的文件名,文件扩展名和文件吗?

以下glob表达式选择除index.pug(filddle)之外的所有.pug文件

/src/!(index){.pug,.haml,index.haml}

现在假设我们已经成功停止了对haml的支持,因此必须从上述表达式中删除所有与haml相关的内容.问题是如何在不从根本上改变其结构的情况下减少上述表达?此条件对于创建简单且同时灵活的全局表达式生成算法很重要.

错误解决方案(.pug文件之间没有匹配项):

/src/!(index){.pug}

下面的解决方案也不适当,因为将来可能会添加新的文件扩展名支持(例如.slim).要实现它,我们必须从根本上改变生成以下表达式的算法.

/src/!(index).pug

下面的解决方案也是不合适的,因为我们不能从中排除任意文件.如果我们要排除index.pug和about.slim但不排除index.slim和about.pug怎么办?

/src/!(index).+(pug|slim)

换句话说:以上所有解决方案都无法在以下任何方面进行扩展:

>必须选择的文件
>文件扩展名,必须选择哪些文件
>带有某些扩展名的文件名,必须将其排除在外.

重要说明:在此问题中,我们不考虑通过glob,globby,gulp.src()等接收文件.我们考虑了单个字符串的生成.

并且:如果以上问题无法用一个字符串解决,请写(如带注释/注释).

最佳答案
为什么不起作用?

您已经遇到了minimatch支持特殊语法. (对于不了解的读者.OP用于说明的站点使用minimatch来评估glob.)您将看到这样的模式:

{a,b,c}

并了解它与名称a,b和c相匹配.括号模式包含一系列用逗号分隔的子模式,如果有任何子模式匹配,则括号模式也会匹配.因此该模式表示“如果文本与OR b OR c匹配,则为匹配”.所以你认为

{a,b}

匹配a和b.或在散文中“如果文本与OR b匹配,则为匹配”.更进一步,您认为可以做到这一点:

{a}

表示“如果匹配,则为匹配”.这相当于仅具有模式a.在没有更好的了解的情况下,有理由认为{a}就是这个意思.在允许对条件列表进行“或”运算的编程语言中,通常可以对仅一个元素的列表执行“或”运算.

但是,minimatch无法以这种方式工作.为了使花括号被识别为表达其他选择,它必须至少包含一个逗号.因此,表达式{a}将使文字输入{a}与花括号和所有内容匹配.

解决方法

您可以修改生成支撑模式的代码,以便如果子模式列表仅包含一个元素,则可以重复执行.要重用您给出的示例,请在括号中两次输入.pug:

/src/!(index){.pug,.pug}

这样一来,括号将被解释为表示替代方案,而不是按字面意义进行解释.通过重复相同的子模式,匹配文件集不会更改.

另一种解决方案是生成一个支撑模式,该支撑模式始终包含一个无法匹配任何内容的元素.例如:

/src/!(index){.pug,!(*)}

最后一个元素不能匹配任何内容,因此它不会添加匹配项,但是它的存在足以使minimatch根据需要解释括号.

为了提供一些背景信息:minimatch对括号的作用称为“括号扩展”.当给minimatch一个模式a {b,c} d时,在执行其他任何操作之前,它将其转换为两个模式:abc和acd,然后如果任何一个模式都匹配,则认为存在匹配项. Brace扩展是Unix shell与其余的globlob语法一起采用minimatch的方式. (其documentation告诉您看到man sh,man bash等)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐