如何独立分割路径平台?

时间:2009-07-08 18:40:25

标签: java regex file cross-platform

我正在使用以下代码从给定路径获取包含所有子目录的数组。

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

我需要数组来检查某些文件夹是否位于此路径中的正确位置。 这看起来是一个很好的解决方案,直到findBugs抱怨File.separator被用作正则表达式。似乎将Windows文件分隔符传递给正在构建正则表达式的函数是一个坏主意,因为反斜杠是一个转义字符。

如何在不使用File.separator的情况下以跨平台方式拆分路径? 或者像这样的代码好吗?

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

6 个答案:

答案 0 :(得分:38)

文字化模式字符串

每当您需要将任意String字面化以用作正则表达式模式时,请使用Pattern.quote

来自API:

  

public static String quote(String s)

     

返回指定String的文字模式String。此方法生成String,可用于创建与Pattern字符串匹配的s,就好像它是文字模式一样。   输入序列中的元字符或转义序列将没有特殊含义。

     

参数: s - 要文字化的字符串
  返回:文字字符串替换

这意味着您可以执行以下操作:

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

字面化替换字符串

如果您需要对任意替换String进行字面化,请使用Matcher.quoteReplacement

来自API:

  

public static String quoteReplacement(String s)

     

返回指定String的文字替换String。此方法生成String,它将作为s类的appendReplacement方法中的文字替换Matcher。生成的String将匹配s中作为文字序列处理的字符序列。斜杠('\')和美元符号('$')将没有特殊含义。

     

参数: s - 要文字化的字符串
  返回:文字字符串替换

此引用的替换StringString.replaceFirstString.replaceAll中也很有用:

  

请注意,替换字符串中的反斜杠(\)和美元符号($)可能会导致结果与将其视为文字替换字符串时的结果不同。如果需要,使用Matcher.quoteReplacement来抑制这些字符的特殊含义。


实施例

    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 :(得分:14)

反复使用path.getParentFile()获取路径的所有组件。

气馁的方式是path.replaceAll("\\", "/").split("/")

答案 2 :(得分: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));
}

方法getNameCountgetName可用于类似目的。

答案 3 :(得分:2)

创建一个空列表,并使用forEach迭代路径元素,将每个元素插入列表中供以后使用:

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

此外,如果您需要特定路径元素,请使用:

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

通过调用<pathObject>返回Paths.get(),如果您需要在字符串中返回路径的多个部分,请使用:

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

您可以使用以下内容获取路径元素的总数(在<intEnd>中使用)

<pathObject>.getNameCount()

Java PathPaths doc页面还有其他有用的方法。

答案 4 :(得分:0)

您可以使用路径界面:

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;
}

答案 5 :(得分:-2)

怎么样?
String[] subDirs = path.split(File.separator.replaceAll("\\", "\\\\"));