Вопрос по file, java, cross-platform, regex – Как разделить путь платформы независимо?

16

Я использую следующий код для получения массива со всеми подкаталогами по заданному пути.

String[] subDirs = path.split(File.separator); 

Мне нужен массив, чтобы проверить, находятся ли определенные папки в нужном месте на этом пути. Это выглядело как хорошее решение, пока findBugs не пожаловался, что File.separator используется как регулярное выражение. Кажется, что передача разделителя файлов Windows в функцию, которая строит регулярное выражение из него, является плохой идеей, потому что обратный слеш является escape-символом.

Как я могу разделить путь кросс-платформенным способом без использования File.separator? Или код, как это хорошо?

String[] subDirs = path.split("/"); 

Ваш Ответ

6   ответов
-2

String[] subDirs = path.split(File.separator.replaceAll("\\", "\\\\"));
2

java.nio.file.Path инвентарьIterable<Path>так что вы можете сделать:

public static void showElements(Path p) {
    List<String> nameElements = new ArrayList<>();
    for (Path nameElement: p)
        nameElements.add(nameElement.toFile().getName());
    System.out.printf("For this file: [%s], the following elements were found: [%s]\n"
                      , p.toAbsolutePath()
                      , Joiner.on(", ").join(nameElements));
}

методыgetNameCount а такжеGetName может быть использован для аналогичной цели.

38

Literalizing pattern strings

Всякий раз, когда вам нужно буквально произвольноString для использования в качестве шаблона регулярного выражения, используйтеPattern.quote:

Из API:

public static String quote(String s)

Returns a literal pattern String for the specified String. This method produces a String that can be used to create a Pattern that would match the string s as if it were a literal pattern. Metacharacters or escape sequences in the input sequence will be given no special meaning.

Parameters: s - The string to be literalized
Returns: A literal string replacement

Это означает, что вы можете сделать следующее:

String[] subDirs = path.split(Pattern.quote(File.separator));

Literalizing replacement strings

Если вам нужно дословно заменить произвольную заменуStringиспользоватьMatcher.quoteReplacement.

Из API:

public static String quoteReplacement(String s)

Returns a literal replacement String for the specified String. This method produces a String that will work as a literal replacement s in the appendReplacement method of the Matcher class. The String produced will match the sequence of characters in s treated as a literal sequence. Slashes ('\') and dollar signs ('$') will be given no special meaning.

Parameters: s - The string to be literalized
Returns: A literal string replacement

Эта цитируемая заменаString также полезно вString.replaceFirst а такжеString.replaceAll:

Note that backslashes (\) and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string. Use Matcher.quoteReplacement to suppress the special meaning of these characters, if desired.


Examples

    System.out.println(
        "O.M.G.".replaceAll(".", "!")
    ); // prints "!!!!!!"

    System.out.println(
        "O.M.G.".replaceAll(Pattern.quote("."), "!")
    ); // prints "O!M!G!"

    System.out.println(
        "Microsoft software".replaceAll("so", "$0")
    ); // prints "Microsoft software"

    System.out.println(
        "Microsoft software".replaceAll("so", Matcher.quoteReplacement("$0"))
    ); // prints "Micro$0ft $0ftware"
1

Создайте пустой список и используйте forEach для перебора элементов пути, вставляя каждый из них в список для дальнейшего использования:

List<String> pathElements = new ArrayList<>();
Paths.get("/foo/bar/blah/baz").forEach(p -> pathElements.add(p.toString()))

Также, если вам нужен конкретный элемент path, используйте:

<pathObject>.getName(<intIndex>).toString() 

где<pathObject> возвращается вызовомPaths.get(), и если вам нужно несколько частей пути, возвращаемого в строке, используйте:

<pathObject>.subPath(<intStart>, <intEnd>).toString()

Вы можете получить общее количество элементов пути (для использования в<intEnd>) с:

<pathObject>.getNameCount()

Есть другие полезные методы в JavaДорожка а такжепути страницы документа.

Пожалуйста, добавьте объяснение, почему ваш код работает и как он решает проблемы в вопросе
Если это дает решение, пожалуйста, предоставьте объяснение, или ответ будет удален.
14

path.getParentFile() повторно получить все компоненты пути.

Discouraged way would be to path.replaceAll("\\", "/").split("/").

Решение getParentFile отлично работает, спасибо Janusz
Да, я ударил обескураженный путь. Сожалею.
+1 есть хакерские способы сделать это и написать способы сделать это. это правильный путь, и он избавит вас от большого количества боли по сравнению с разделением символом-врезкой «/ / apos ;," \ ", для которого вы полностью забыли здесь & gt;
0

Вы можете использовать интерфейс Path:

Path p = Paths.get(pathStr);
for (int i = 0; i < p.getNameCount(); i++) {
    String name = p.getName(i).toString();
    //do what you need with name;
}

Похожие вопросы