如何检查路径是绝对路径还是相对路径

47

UNIX绝对路径以'/'开头,而Windows以字母'C:'或'\'开头。Node.js是否有标准的多平台函数来检查路径是绝对还是相对的?

6个回答

71
自从Node版本0.12.0起,您可以使用path.isAbsolute(path)函数来自path模块。

i.e:

var path = require('path');
if(path.isAbsolute(myPath)) {
    //...
}

4
请注意,isAbsolute 似乎会对任何以 / 开头的路径返回 true,无论是在 Windows 还是 Mac 上(不确定 *nix 是否也是如此)。 - Alexander Mills
1
正如Alexander Mills所指出的那样,这个答案是错误的。如果你的相对路径以“/”开头(通常所有相对路径都是这样),那么这种方法将返回true,这是错误的。我不知道为什么它被选为正确答案,这是危险的,会使SO变得不可靠。 - Kawd
7
这个回答是正确的。也许你在考虑相对路径的 HTTP URL 方面?Node.js 工具 path.isAbsolute 用于文件系统路径,其中“绝对路径”定义为以斜杠开头。例如,请参阅 http://www.linfo.org/path.html。 - Chris Arnesen
1
请注意,当在Unix或类Unix系统上处理以~开头的路径时,isAbsolute会返回false。虽然这些路径确实是相对于当前用户目录的,但它们不是相对于当前目录的,因此改变目录不会影响它们的解析。从这个意义上讲,这些路径是绝对的,这可能会让一些人感到惊讶。 - ErikE

12
你可以使用
path.resolve(yourPath)===yourPath

如果您的路径未经过规范化,请使用

path.resolve( yourPath ) == path.normalize( yourPath )

4
源代码中也有一个isAbsolute函数,即使我在文档中找不到它,它似乎也无法使用:https://github.com/joyent/node/blob/master/lib/path.js#L206 - Denys Séguret
是的,我不知道为什么文档中没有提到,但现在我认为出于安全考虑,我将使用您的回复。 - Manuel Di Iorio
2
该函数实际上是在不稳定的版本(0.11)中存在,而不是在最新的稳定版本中。 - Denys Séguret
3
如果yourPath没有被规范化,这个方法将无法正常工作(例如:对于///a//..//b//不起作用)。正确的解决方案是:path.resolve( yourPath ) == path.normalize( yourPath ) - peoro
我相信以下代码更加健壮:function isAbsolute(p) { return path.normalize(p + '/') === path.normalize(path.resolve(p) + '/'); } - TomDotTom
显示剩余2条评论

10

根据dystroy所说的评论,如果绝对路径没有被规范化(例如路径:///a//..//b//./),那么提出的解决方案是无效的。

一个正确的解决方案是:

path.resolve(yourPath) === path.normalize(yourPath)

正如Marc Diethelm在评论中提到的那样,这个方法仍然存在一些问题,因为path.resolve会删除尾部斜杠,而path.normalize则不会。

我不确定这些函数的确切行为(正如您可以从评论中读到的那样),但是以下代码片段似乎在至少Linux环境中运行良好:

path.resolve(yourPath) === path.normalize(yourPath).replace( RegExp(path.sep+'$'), '' );

1
然而,由于normalize保留尾随斜杠,因此您的解决方案需要进行改进。 path.resolve(_yourPath) === path.normalize(_yourPath).replace(/[\/|\\]$/, '') 将能够可靠地工作。 - Marc Diethelm
@MarcDiethelm:你说得很对,我从未注意到。我会尝试根据您的建议修复答案!无论如何,您的解决方案仍然不完美,例如它在'/\\'中失败。有没有特定的原因要删除尾随反斜杠?是为了支持Windows路径还是其他什么? - peoro
在Windows上,确切地检查尾随反斜杠是必要的。关于此,它会失败并显示“/\”。我不明白,你能详细说明一下吗?那应该是你要测试的路径吗? - Marc Diethelm
@MarcDiethelm:是的,完全正确。我正在Linux机器上运行Node。如果我将'/\\'字符串传递给您的函数,则path.resolve('/\\')返回'/\\',而path.normalize('/\\').replace(/[\/|\\]$/, '')返回'/'。我在此响应中添加的行在Linux上似乎很好用,但可能会有其他问题(也许在Windows上?)。 - peoro
路径 '/\\' 对我来说似乎是一个真正的边缘情况。也许先尝试取消转义?我不喜欢在这里调用 RegExp 构造函数及其所有开销。path.sep 一开始看起来很好。但基本上我们只想在比较之前删除任何(Windows 或其他)尾部斜杠。这是我的修改版本,它适用于根路径 '/'path.resolve(yourPath) === path.normalize(yourPath).replace(/(.+)([\/|\\])$/, '$1') - Marc Diethelm
这在Windows上与node v0.10.35不兼容。如果你使用没有驱动器字母的绝对路径,这将失败,因为path.normalize()不会添加驱动器字母。 - vulcan raven

3

这有点复杂,但是我发现使用旧版(0.12.0之前)的路径模块是最健壮的方法。

function isAbsolute(p) {
    return path.normalize(p + '/') === path.normalize(path.resolve(p) + '/');
}

注意:path.isAbsolute从node 0.12.0版本开始存在。


2

我对node.js一无所知,但你可以在github上查看path.js的源代码:https://github.com/joyent/node/blob/master/lib/path.js

你会发现:

// windows version
exports.isAbsolute = function(path) {
    var result = splitDeviceRe.exec(path),
    device = result[1] || '',
    isUnc = device && device.charAt(1) !== ':';
    // UNC paths are always absolute
    return !!result[2] || isUnc;
};

And:

// posix version
exports.isAbsolute = function(path) {
    return path.charAt(0) === '/';
};

-1
    isRelative(url){
        return (/^(\.){1,2}(\/){1,2}$/.test(url.slice(0,3)) ||
        /(\/){1,2}(\.){1,2}(\/){1,2}/.test(url)); 
    }

这使得即使没有节点路径模块API,检查路径是否相对容易。

(/^(\.|~){1,2}(\/){1,2}$/.test(url.slice(0,3))

这部分检查路径字符串是否以"./"、"../"或"~/"开头。如果是,则返回布尔值true。否则执行下一个测试。

/(\/){1,2}(\.){1,2}(\/){1,2}/.test(url)

这个函数检查路径字符串是否包含 "/./" 或者 "/../",如果包含则返回 true,否则返回 false。

如果两个测试中有任意一个为 true,则说明路径字符串是相对路径。

适用于 Windows 系统。

    isRelative(url){
        return (/^(\.){1,2}(\\){1,2}$/.test(url.slice(0,3)) ||
        /(\\){1,2}(\.){1,2}(\\){1,2}/.test(url)); 
    }

1
请解释一下你所做的事情。 - Abhishek Pandey
你如何将以 ~ 开头的路径定义为相对路径?它们可能是相对路径,但不是相对于当前目录。似乎有三种状态,而 isAbsolute 是一个糟糕的函数,因为它会误导。以 ~ 开头的路径是稳定的,并且不会随着当前目录的更改而更改;从这个意义上说,它们是绝对路径... - ErikE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接