在JAVA中的glob语法中什么时候要使用**(双星号)?

70

直接引用Java Oracle教程:

两个星号 ** 的作用类似于 *,但是会跨越目录边界。该语法通常用于匹配完整路径。

有人能够根据它做一个真实的例子吗? 他们说的“跨越目录边界”是什么意思呢? 我想,跨越目录边界可能是从根目录到 getNameCount()-1 检查文件。 再次给出一个在实践中解释 * 和 ** 差异的真实示例将会很棒。


这意味着它将递归地遍历所有子目录,其中 * 仅获取当前目录中的文件,忽略子目录。 - StormeHawke
2个回答

77

FileSystem#getPathMatcher() 的 JavaDoc 文档提供了一些很好的示例和解释。

*.java Matches a path that represents a file name ending in .java 
*.*    Matches file names containing a dot 

*.{java,class}  Matches file names ending with .java or .class 
foo.?           Matches file names starting with foo. and a single character extension 
/home/*/*       Matches /home/gus/data on UNIX platforms 
/home/**        Matches /home/gus and /home/gus/data on UNIX platforms 
C:\\*           Matches C:\foo and C:\bar on the Windows platform (note that the backslash is escaped; as a string literal in the Java Language the pattern would be "C:\\\\*")  

因此,/home/**会匹配/home/gus/data,但/home/*不会。

/home/*表示匹配/home目录下的每一个文件。

/home/**表示匹配/home任意子目录中的每个文件。


***的示例。假设您当前的工作目录是/Users/username/workspace/myproject,那么以下内容只会匹配./myproject文件(目录)。

PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher("glob:/Users/username/workspace/*");
Files.walk(Paths.get(".")).forEach((path) -> {
    path = path.toAbsolutePath().normalize();
    System.out.print("Path: " + path + " ");
    if (pathMatcher.matches(path)) {
        System.out.print("matched");
    }
    System.out.println();
});

如果使用**,它将匹配该目录中的所有文件夹和文件。


29

双星号(**)可以匹配多个嵌套目录中的零个或多个字符。在解释主要概念之后,我将逐步用示例来解释双星号以及其他有用的通配符。


Globbing

Globbing是一种使用字符串文本和/或通配符字符来匹配文件路径的方法。使用一个或多个glob来定位文件系统上的文件称为globbing。Globbing不仅仅局限于Java,它还用于匹配各种配置文件中的文件,例如在Git中列出被忽略的文件和目录的.gitignore,在Unix操作系统中选择文件和文件夹,例如 ls **/*.java 等。

以下是globbing的一些最重要的部分。双星号(**)是其中之一:


分隔符和段(/)

在Globbing中,无论使用何种操作系统,斜杠字符(/)始终作为分隔符。一个指的是两个分隔符之间的所有内容。

例如: tests/HelloWorld.java

这里,testsHelloWorld.java是段,/是分隔符。


单个星号(*)

单个星号(*)匹配一个中的零个或多个字符。它用于在一个目录中进行文件的globbing。

例子: *.java

这个通配符可以匹配像 HelloWorld.java 这样的文件,但不能匹配像 tests/HelloWorld.javatests/ui/HelloWorld.java 这样的文件。


双星号 (**)

双星号 (**) 可以匹配跨越多个段落的零个或多个字符。它用于匹配嵌套目录中的文件。

例子: tests/**/*.java

在这里,文件选择将被限制在tests目录中。该通配符将匹配像 tests/HelloWorld.java, tests/ui/HelloWorld.java, tests/ui/feature1/HelloWorld.java 这些文件。


问号(?)

问号(?) 可以匹配一个段落中的单个字符。它可以用于匹配文件名或文件夹名只有一个字符不同的文件。

例子: tests/?at.java

这将匹配像 tests/cat.java, test/Cat.java, test/bat.java 等文件。


方括号 ([abc])

方括号 ([...]) 可以匹配方括号中给定的一个字符。

例子: tests/[CB]at.java

这个通配符将匹配类似 tests/Cat.javatests/Bat.java 的文件。


方括号范围 ([a-z])

Square Brackets Range ([a-z]), 匹配范围内的一个字符。

例如: tests/feature[1-9]/HelloWorld.java

这个表达式将匹配到像tests/feature1/HelloWorld.java, test/feature2/HelloWorld.java等文件,一直到9


Negation (!)

Negation (!) 用于排除某些文件。

例如:tests/[!C]at.java

这将排除文件tests/Cat.java,并匹配tests/Bat.javatests/bat.javatests/cat.java等文件。


就是这样!希望这有所帮助。


我犯了一个错误,我实际上使用的是不支持Globstar的旧版本bash。 - Jack Cole

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接