如何编写匹配除指定文件夹外所有文件的glob模式,解决Ruby File.fnmatch适配问题
问题原因
你遇到的匹配失败问题来自两个核心原因:
- Ruby的
File.fnmatch默认不支持!(pattern)这类扩展glob语法,需要额外传入FNM_EXTGLOB参数手动开启该特性。你对比的JavaScript glob类库大多默认开启了扩展glob支持,所以两者行为不一致。 - 你当前写的
!(foo)/**/*要求匹配的路径必须至少包含2个路径段(第一个路径段不为foo,后面至少还有1个路径段),根目录下的直接文件(比如README.md)无法被该模式匹配。
修正方案
场景1:只需匹配非foo开头的多级路径
保留你原来的模式,调用File.fnmatch时传入FNM_EXTGLOB参数即可:
# 测试匹配非foo目录的多级路径 File.fnmatch("!(foo)/**/*", "hello/world.js", File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB) # => true File.fnmatch("!(foo)/**/*", "test/some/globs", File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB) # => true File.fnmatch("!(foo)/**/*", "foo/bar/something.txt", File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB) # => false
场景2:需要匹配所有非foo目录下的文件,包含根目录直接文件
调整模式为{*,!(foo)/**/*},同时开启FNM_EXTGLOB参数:
# 测试覆盖根目录文件 File.fnmatch("{*,!(foo)/**/*}", "README.md", File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB) # => true File.fnmatch("{*,!(foo)/**/*}", ".gitignore", File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB) # => true File.fnmatch("{*,!(foo)/**/*}", "foo/config.yml", File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB) # => false
内容的提问来源于stack exchange,提问作者Rahul Z
相关产品推荐
相关产品推荐

