登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  java教程

Java FileSystem.getPathMatcher 怎样区分 glob 与 regex

来源:17golang原创

时间:2026-11-12 01:00:05 496浏览 收藏

Java FileSystem.getPathMatcher 怎样区分 glob 与 regex

Java NIO 按路径筛文件时,getPathMatcher() 的关键不是“哪个更强”,而是先确认你要匹配的是简单文件名规则,还是完整路径约束。默认文件系统支持 glob 和 regex 两种语法,参数统一写成 syntax:pattern。

官方地址:https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String)

简单记忆:扩展名、目录层级和少量通配符优先用 glob;需要分组、边界、字符类或完整路径约束时再用 regex。两者最终都返回 PathMatcher,通过 matches(Path) 判断。

理解 syntax:pattern 参数

FileSystem.getPathMatcher(String syntaxAndPattern) 接收一个非空语法名、冒号和模式字符串。语法名比较时不区分大小写,但模式本身仍要按照对应语法解释。

Java getPathMatcher 从 syntax pattern 到 glob regex 和 PathMatcher 的结构说明图
图1:getPathMatcher 语法入口与 PathMatcher 接口的结构说明图。
FileSystem fileSystem = FileSystems.getDefault();

// 语法名决定后面的模式如何解释
PathMatcher globMatcher = fileSystem.getPathMatcher("glob:*.java");
PathMatcher regexMatcher = fileSystem.getPathMatcher("regex:.*\\\\.(java|kt)$");

Path source = Path.of("Report.java");
// matches 接收 Path,比较的是 Path 的字符串表示
boolean byGlob = globMatcher.matches(source);
boolean byRegex = regexMatcher.matches(source);

这里的 regex 示例有两层转义:Java 字符串先把反斜杠写成 \\,再交给正则表达式引擎解释。正则表达式本身写对了,但 Java 字符串少一个反斜杠,结果就可能完全不同。

用 glob 表达常见文件名规则

glob 更接近文件筛选习惯。* 匹配一个名称组件中的零个或多个字符,不跨目录边界;** 才允许跨目录边界;? 匹配一个字符;{java,class} 表示多个候选分支。

FileSystem fileSystem = FileSystems.getDefault();

// 只关注当前名称组件的 Java 文件
PathMatcher currentDirJava = fileSystem.getPathMatcher("glob:*.java");
// ** 用来覆盖任意深度的目录层级
PathMatcher allJava = fileSystem.getPathMatcher("glob:**/*.java");
// 花括号适合少量固定后缀,不要把它当成正则分组
PathMatcher sourceFiles = fileSystem.getPathMatcher("glob:**/*.{java,kt}");

如果你传入 src/main/App.java,glob:*.java 是否匹配取决于整个 Path 字符串的名称组件边界;它不是“只取最后一个文件名再比较”。需要覆盖任意目录层级时,直接把目录部分写进模式,通常更清楚。

Java PathMatcher 中 glob 通配符与 regex 转义对比的结构说明图
图2:glob 与 regex 的路径表达边界说明图。

用 regex 表达完整路径约束

regex 适合表达更细的规则,例如只允许两个扩展名、要求文件名以某个前缀开头,或需要把目录和文件名放进同一条约束中。

FileSystem fileSystem = FileSystems.getDefault();

// 正则匹配的是 Path.toString() 的结果,分隔符需按平台考虑
PathMatcher releaseArtifact = fileSystem.getPathMatcher(
    "regex:.*/release-[0-9]+\\\\.(zip|jar)"
);

Path artifact = Path.of("build", "release-2026.jar");
// 代码示例只表达匹配规则,实际项目应先明确路径格式
boolean matched = releaseArtifact.matches(artifact);

regex 的代价是可读性和转义复杂度更高。跨平台代码不要把 Unix 的 / 直接当成唯一分隔符;如果规则只关心最后一个名称组件,先取得文件名再匹配,往往比把平台路径拼进正则更稳。

按任务选择并复查边界

需求优先选择原因
按后缀筛选glob模式短,读者一眼能看懂
跨目录查找glob + **直接表达目录层级
多条件命名规则regex支持字符类、数量和分组
跨平台路径先明确 Path 字符串避免把分隔符当成固定字符

遇到 PatternSyntaxException,先检查 regex;遇到 UnsupportedOperationException 或不支持的语法,确认当前文件系统提供者支持哪些 syntax。默认文件系统支持 glob 与 regex,但自定义文件系统不一定提供额外语法。

常见问题

glob 的 * 能匹配多级目录吗?

不能把它理解成跨目录通配符。单个 * 不跨名称组件,目录层级场景应考虑 **,并把期望的路径结构写完整。

PathMatcher 是不是只匹配文件名?

不是。它匹配传入 Path 的字符串表示,因此相对路径、绝对路径和平台分隔符都会影响结果。

什么时候不该用 PathMatcher?

如果还需要遍历目录、读取属性或处理访问异常,PathMatcher 只负责模式判断,遍历和资源关闭应交给对应的 NIO API。

最终判断可以压缩成一句话:简单目录/扩展名规则用 glob,复杂字符约束用 regex;无论选哪种,都先确认“被匹配的 Path 字符串到底长什么样”。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>