Java里如何使用PathMatcher完成路径模式匹配_Java文件匹配规则解析

PathMatcher 是 Java NIO.2 提供的轻量级路径匹配工具,支持 glob 和 regex 两种模式,基于 FileSystem 创建、线程安全;glob 语法简洁常用(如 */.java),regex 更灵活但需注意转

义与路径分隔符处理。

Java 中的 PathMatcher 是 NIO.2 提供的轻量级路径匹配工具,适合做文件/目录路径的规则判断(比如过滤日志、扫描资源、忽略某些路径),它不支持正则表达式,而是基于简洁的 glob 或 regex 语法,由 FileSystem 创建,线程安全,开销小。

一、PathMatcher 的两种模式:glob 和 regex

glob 是最常用的方式,语法简单直观,适合大多数路径匹配场景;regex 更强大但需注意转义和路径分隔符处理(如 Windows 的 \ 需双写或用正斜杠)。

  • glob 示例:**/*.java 匹配任意层级下的所有 Java 文件;config/*.properties 匹配 config 目录下一级的 properties 文件
  • regex 示例:regex:^.*\\.xml$(注意开头的 regex: 前缀);Windows 路径建议统一用 /Pattern.quote() 处理分隔符
  • 创建方式:FileSystems.getDefault().getPathMatcher("glob:**/*.log")

二、glob 通配符规则详解

glob 不是正则,它的符号含义固定且有限:

  • *:匹配当前目录下任意**不含**路径分隔符的文件名(如 *.txta.txt,但不匹配 sub/a.txt
  • **:匹配**跨目录层级**的任意路径(如 **/*.mdREADME.mddocs/api.mdsrc/test/notes.md
  • ?:匹配任意单个字符(不含分隔符,如 ?.loga.log,但不匹配 ab.log
  • [abc][a-z]:匹配方括号内任一字符(类似正则字符类)
  • 字面量字符(包括 .- 等)直接匹配,无需转义(.java 就是匹配字面量点+java)

三、实际使用示例:遍历并过滤文件

结合 Files.walk()PathMatcher 可高效筛选路径:

PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**/{*.java,*.xml}");
try (Stream stream = Files.walk(Paths.get("src"))) {
    stream.filter(matcher::matches)
          .forEach(System.out::println);
}
  • 注意:{a,b} 是 glob 的“组匹配”扩展(JDK 7+ 支持),表示“a 或 b”,不是所有 FileSystem 都支持,推荐优先用多个 matcher 或逻辑 or
  • 路径传入 matcher.matches(path) 时,path 应为相对路径或与 pattern 语义一致(例如 pattern 是 **/*.log,传入 Paths.get("a/b/c.log") 没问题;若 pattern 是 logs/*.log,就应确保 path 是相对于 logs 的,或改用绝对路径 + 更宽泛 pattern)
  • 大小写敏感性取决于底层文件系统(Linux 默认敏感,Windows 默认不敏感),如需强制不敏感,可用 regex:(?i).*\.java

四、常见坑与注意事项

用错 pattern 或忽略环境细节容易导致匹配失败:

  • ** 必须单独成段(如 foo/**/bar 合法,foo**bar 非法)
  • Windows 路径中反斜杠 \ 在字符串里要写成 \\,但更稳妥的是全部用正斜杠 /(NIO 接口内部自动适配)
  • PathMatcher 不解析符号链接,匹配的是路径字符串本身,不是真实文件属性
  • 如果 pattern 以 / 开头(如 /home/**/*.txt),它会尝试匹配绝对路径;一般建议 pattern 不带根,靠输入 path 控制范围

基本上就这些。PathMatcher 不复杂但容易忽略语义边界,用好 glob 规则比硬套正则更稳更快。