Java 7 PathMatcher:**匹配0个目录吗?

时间:2016-03-04 09:56:47

标签: java path

看一下以下示例:

public class Test {
    public static void main(String[] pArgs) throws Exception {
        final PathMatcher pm = FileSystems.getDefault().getPathMatcher("glob:**/*.java");
        final Path p = Paths.get("Test.java");
        System.out.println("Match = " + pm.matches(p));
    }
}

我希望输出为"Match = true",但实际输出为"Match = false"

换句话说:模式**是否匹配0个目录,我期望它?或者它是否匹配一个或多个目录?

2 个答案:

答案 0 :(得分:0)

来自getPathMatcher文档:

  

以下规则用于解释glob模式:

     
      
  • **个字符匹配跨越目录边界的零个或多个字符。
  •   

这意味着**/*.java会匹配,例如/Test.javasome/directory/Test.java。但是领先的斜杠仍将出现在匹配的模式中,这意味着它不会匹配Test.java

您不应将**视为0个或更多目录,而应将0个或多个字符视为跨越目录边界。

答案 1 :(得分:0)

作为@Tunaki答案的补充,您可以使用{}和由,分隔的子模式来使用替代方案。它不接受替代方案(例如:你不能{a,b{0,1},c})。

要使代码正常工作,请按预期使用模式glob:{,**/}*.java代替"glob:**/*.java"

它会:

  • 匹配*.java(例如Paths.get("Test.java")
  • 匹配**/*.java(例如Paths.get("src/main/java/Test.java")

如果您想了解有关glob实现的更多详细信息,可以在JDK sources

中找到它

总结一下,它们只是被翻译成一个简单的" Pattern{,**/}*.java在Windows上翻译为^(|\*\*\\}.*\.java$,否则翻译为^(|\*\*/}.*\.java$;然后将Path的toString与该模式进行匹配。

如果您使用其他FileSystem实施(例如JimFsmemoryfilesystemTrueVFS),则最后一部分很重要,因为它只是意味着{{1} }由PathMatcher生成,它实际上接受任何FileSystem,并且不会为Path生成的路径产生异常。