【问题标题】:Java PathMatcher: why ** doesn't work for zero folders?Java PathMatcher:为什么 ** 对零文件夹不起作用?
【发布时间】:2021-04-01 11:06:39
【问题描述】:

我正在尝试使用 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 匹配 foo.php // OK foo.php 不匹配 sub/foo.php // OK **/foo.php 匹配 sub/foo.php // OK **/foo.php 不匹配 foo.php // KO,为什么 ????

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

【问题讨论】:

    标签: java glob


    【解决方案1】:

    来自documentation

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

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

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

    来实现此目的

    { } 字符是一组子模式,如果组中的任何子模式匹配,则该组匹配。 "," 字符用于分隔子模式。组不能嵌套。

    【讨论】:

    • 感谢您的回答。我正要说它对我来说仍然看起来像一个错误(在引擎盖下使用字符串匹配,而它应该考虑路径段)。但我只是在 bash 中做了一个快速测试,我也有同样的行为。 ls **/foo.php 没有返回当前目录中文件的匹配项......所以我认为这只是我有一个不好的期望:)
    • @JulienH。很高兴我能帮助你。我认为**/foo.php 是这样的:** 匹配任何目录(也可以为空),但必须跟在/foo.php 后面,所以,至少对我来说,很清楚为什么foo.php 不会匹配。
    • 我发现奇怪的是,没有简单的方法来查找特定文件名,无论文件夹是什么(递归搜索)。
    猜你喜欢
    • 2014-10-05
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    • 2012-09-04
    • 2016-08-07
    相关资源
    最近更新 更多