Java PathMatcher:为什么 ** 对零文件夹不起作用?

Java PathMatcher: why ** doesn't work for zero folders?

我正在尝试使用 PathMatcher 匹配相对路径。一个非常常见的情况是使用像 **/foo.php 这样的模式来匹配所有名为 foo.php 的文件,无论它们在哪个文件夹中。 但是当文件实际上不在任何文件夹中时,我发现了一种对我来说看起来不对的行为:

import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;

public class PathMatcherTest {

  public static void main(String[] args) {
    testMatch("foo.php", Paths.get("foo.php"));
    testMatch("foo.php", Paths.get("sub/foo.php"));
    testMatch("**/foo.php", Paths.get("sub/foo.php"));
    testMatch("**/foo.php", Paths.get("foo.php"));
  }

  private static void testMatch(String pattern, Path path) {
    PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
    if (pathMatcher.matches(path)) {
      System.out.println(pattern + " matches " + path);
    } else {
      System.out.println(pattern + " doesn't matches " + path);
    }
  }

}

产生:

foo.php matches foo.php // OK
foo.php doesn't matches sub/foo.php // OK
**/foo.php matches sub/foo.php // OK
**/foo.php doesn't matches foo.php // KO, why ????

为什么 GLOB 模式 **/foo.php 不匹配 foo.php?我是不是误读了规范,还是一个错误?

来自documentation

The ** characters matches zero or more characters crossing directory boundaries.

使用您的模式 **/foo.php 很容易看出它为什么不起作用。因为 ** 可以为空,所以匹配器实质上检查 foo.php 是否匹配 /foo.php(显然不应该,一个位于当前文件夹中,另一个位于根目录中)。

要解决此问题:您可以使用子模式来匹配文件不在任何文件夹中的情况。您可以通过将模式更改为 {foo.php,**/foo.php}

来实现此目的

The { } characters are a group of subpatterns, where the group matches if any subpattern in the group matches. The "," character is used to separate the subpatterns. Groups cannot be nested.