Windows 上的路径分隔符不明确 - 如何处理?

Ambiguous path separator on Windows - how to handle it?

提出了一个有趣的问题:

在 Windows 上,Java File.pathSeparatorChar;,这是正确的。但是,分号实际上 也是 文件夹或文件名的有效字符。您可以在 Windows.

上创建一个名为 Test;Test1 的文件夹

问题是:如果路径列表可以同时包含绝对路径和相对路径,您将如何确定路径列表中的分号实际上是分隔路径还是目录名称的一部分?

在 Windows PATH 中,分号始终是分隔符。如果您有一个名称中带有分号的文件夹,您可以将其简短的备用名称放在 PATH 中。要查找短名称,请使用 DIR /X。例如:

C:\> dir test* /X
<DIR>   **TEST_T~1**     Test;Test1
C:\> set PATH=TEST_T~1;%PATH%

如果路径包含 ; 本身,则路径必须用双引号括起来 ".

以下小型 PoC

mkdir "foo;bar"
echo echo execute %%~dpnx0 > "foo;bar\dummy.cmd"
set PATH=%PATH%;"foo;bar"
dummy.cmd

输出将是

execute R:\temp\foo;bar\dummy.cmd

表示dummy.cmd是通过路径设置找到的

edit 从评论中可以看出:使用半克隆可能会给您带来麻烦。最好避免使用包含分号的目录名称。

由于问题是针对 Java,并且基于 @SubOptimal 解释带有分号的路径应该用引号括起来,这里有一个小代码示例来从这样的路径中提取路径由 File.pathSeparator:

分隔的列表
String separatedList  = "\"test;test1\";c:\windows;\"test2\";test3;;test4";

String pattern = String.format("(?:(?:\"([^\"]*)\")|([^%1$s]+))%1$s?", File.pathSeparator);
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(separatedList);
while (m.find())
{
    for (int i = 1; i <= m.groupCount(); i++)
    {
        String path = m.group(i);
        if (path != null)
            System.out.println(path);
    }
}

作为参考,没有转义字符的正则表达式是 (?:(?:"([^"]*)")|([^;]+));?