处理分割Windows或Linux路径的最佳方法


Best way to handle splitting a Windows or Linux path

我有两个字符串:

C:'Users'Bob'My Documents
/Users/Bob/Documents

我已经设法变出了这个正则表达式:

preg_split('/(?<=['/'''])(?!['/'''])/', $string)

返回

Array
(
    [0] => C:'
    [1] => Users'
    [2] => Bob'
    [3] => My Documents
)
Array
(
    [0] => /
    [1] => Users/
    [2] => Bob/
    [3] => Documents
)

然而,我正在寻找

Array
(
    [0] => C:'
    [1] => Users
    [2] => Bob
    [3] => My Documents
)
Array
(
    [0] => /
    [1] => Users
    [2] => Bob
    [3] => Documents
)

为什么不只是检查"/"或"'",然后使用explode与适当的分隔符?

<?php
$s1 = 'C:''Users''Bob''My Documents';
$s2 = '/Users/Bob/Documents';
function mySplit($s) {
    if(strpos($s, '/') !== false) {
        $d = '/';
    }elseif(strpos($s,'''') !== false) {
        $d = '''';
    }else {
        throw new Exception('Valid delimiter not found.');
    }
    $ret = explode($d, $s);
    $ret[0] .= $d;
    return $ret;
}
echo '<pre>' . print_r(mySplit($s1),true) . '</pre>';
echo '<pre>' . print_r(mySplit($s2),true) . '</pre>';
?>

(更新为稍微整洁的版本)

$dirs = explode(DIRECTORY_SEPARATOR, $string);
$dirs[0] .= DIRECTORY_SEPARATOR;

使用下面的代码,您将得到您想要的,但是第一个键也将没有斜杠:

preg_split('#(?<=)[/''']#', $string);

我知道你已经接受了一个答案,但是有一个非常简单的,一行的解决方案,我经常使用这个问题,我觉得它需要张贴在这里:

$pathParts = explode('/', rtrim(str_replace('''', '/', $path)));

这将用正斜杠替换反斜杠,修剪任何尾随斜杠,并爆炸。这可以安全地完成,因为windows路径不能包含正斜杠,linux路径不能包含反斜杠。

生成的数组看起来与上面描述的不完全相同——路径的根部分不包含斜杠——但实际上这样表示更好。这是因为当与斜杠一起存储时,路径的根(即C:'或'/')实际上并不那么有用。这样做的结果,你可以调用implode('/', $pathParts);并获得一个有效的路径回来,而你的数组,你最终会在根有一个额外的斜杠。此外,'Users'User'My Documents(没有驱动器号)仍然是Windows上的有效路径,它只是暗示当前的工作卷。