Когда использовать ** (двойную звезду) в синтаксисе glob в JAVA

Непосредственно из этого руководства по Java Oracle:

Две звездочки, **, работают так же, как *, но пересекают границы каталога. Этот синтаксис обычно используется для сопоставления полных путей.

Может ли кто-нибудь сделать реальный пример из этого? Что они имеют в виду под «пересекает границу каталога»? Пересекая границу каталога, я представляю что-то вроде проверки файла от корня до getNameCount()-1. Опять же, реальный пример, объясняющий разницу между * и ** на практике, был бы замечательным.


person Rollerball    schedule 10.09.2013    source источник
comment
Это означает, что он будет рекурсивно проходить через все подкаталоги, где * будет захватывать файлы только из текущего каталога, игнорируя подкаталоги.   -  person StormeHawke    schedule 10.09.2013


Ответы (2)


Документ Javadoc для FileSystem#getPathMatcher() содержит несколько довольно хороших примеров и объяснений

*.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();
});

Если вы используете **, он будет соответствовать всем папкам и файлам в этом каталоге.

person Sotirios Delimanolis    schedule 10.09.2013

Двойная звездочка (**) соответствует нулю или более символов в нескольких вложенных каталогах. Я объясню двойную звездочку, а также другие полезные подстановочные знаки шаг за шагом с примерами после объяснения основной концепции.


Глоббинг

glob — это строковый литерал и/или подстановочные знаки, используемые для сопоставления путей к файлам. Поиск файлов в файловой системе с использованием одного или нескольких подстановочных знаков называется подстановкой. Подстановка не ограничивается только Java. Он также используется для сопоставления файлов в различных файлах конфигурации, таких как перечисление игнорируемых файлов и каталогов в .gitignore в Git, выбор файлов и папок в операционной системе Unix, например ls **/*.java и т. д.

Ниже приведены некоторые из наиболее важных частей подстановки. Двойная звездочка (**) — одна из них:


Разделитель и сегменты (/)

В Globbing символ косой черты (/) всегда действует как разделитель, независимо от того, какая операционная система используется. Сегмент — это все, что находится между двумя разделителями.

Пример: tests/HelloWorld.java

Здесь tests и HelloWorld.java — это сегменты, а / — разделитель.


Одиночная звездочка (*)

Одинарная звездочка (*) соответствует нулю или более символов в пределах одного сегмента. Он используется для объединения файлов в одном каталоге.

Пример: *.java

Этот шаблон будет соответствовать таким файлам, как HelloWorld.java, но не таким файлам, как tests/HelloWorld.java или tests/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.java или tests/Bat.java.


Диапазон квадратных скобок ([a-z])

Диапазон квадратных скобок ([a-z]) соответствует одному символу, указанному в диапазоне.

Пример: tests/feature[1-9]/HelloWorld.java

Этот глобус будет соответствовать таким файлам, как tests/feature1/HelloWorld.java, test/feature2/HelloWorld.java и так далее... вплоть до 9.


Отрицание (!)

Отрицание (!) используется для исключения некоторых файлов.

Пример: tests/[!C]at.java

Это исключит файл tests/Cat.java и будет соответствовать таким файлам, как tests/Bat.java, tests/bat.java, tests/cat.java.


Вот и все! Надеюсь, это поможет.

person Yogesh Umesh Vaity    schedule 20.07.2020