是否有类似于 os.path.join 的内置 javascript 函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29855098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 11:11:57  来源:igfitidea点击:

Is there a built-in javascript function similar to os.path.join?

javascriptpython

提问by aensm

Is there a built-in javascript function that functions similarly to python's os.path.join? I know I can join strings in the following manner:

是否有与 python 类似的内置 javascript 函数os.path.join?我知道我可以通过以下方式加入字符串:

['a', 'b'].join('/')

The problem is that if the strings already contain a leading/trailing "/", then they will not be joined correctly, e.g.:

问题是,如果字符串已经包含前导/尾随“/”,那么它们将无法正确连接,例如:

['a/','b'].join('/')

Edit:Should have specified that I'm doing this client-side.

编辑:应该指定我在做这个客户端。

采纳答案by Rob M.

There isn't currently a built-in that will perform a join while preventing duplicate separators. If you want concise, I'd just write your own:

目前没有内置的可以在防止重复分隔符的同时执行连接。如果你想要简洁,我只会写你自己的:

function pathJoin(parts, sep){
   var separator = sep || '/';
   var replace   = new RegExp(separator+'{1,}', 'g');
   return parts.join(separator).replace(replace, separator);
}

var path = pathJoin(['a/', 'b', 'c//'])

回答by Carsten

Use the pathmodule. path.joinis exactly what you're looking for. From the docs:

使用path模块。path.join正是你要找的。从文档

path.join([path1][, path2][, ...])#Join all arguments together and normalize the resulting path.

Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown.

Example:

path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')
// returns
'/foo/bar/baz/asdf'

path.join('foo', {}, 'bar')
// throws exception
TypeError: Arguments to path.join must be strings

path.join([path1][, path2][, ...])#将所有参数连接在一起并规范化生成的路径。

参数必须是字符串。在 v0.8 中,非字符串参数被默默忽略。在 v0.10 及更高版本中,抛出异常。

例子:

path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')
// returns
'/foo/bar/baz/asdf'

path.join('foo', {}, 'bar')
// throws exception
TypeError: Arguments to path.join must be strings

Edit:

编辑:

I assumed here that you're using server-side Javascript like node.js. If you want to use it in the browser, you can use path-browserify.

我在这里假设您正在使用像 node.js 这样的服务器端 Javascript。如果你想在浏览器中使用它,你可以使用path-browserify

回答by leo

Building on @Berty's reply, this ES6 variant preserves all leading slashes, to work with protocol relative url's(like //stackoverflow.com), and also ignores any empty parts:

基于@Berty 的回复,这个 ES6 变体保留了所有前导斜杠,以使用协议相关 url(如//stackoverflow.com),并忽略任何空部分:

build_path = (...args) => {
  return args.map((part, i) => {
    if (i === 0) {
      return part.trim().replace(/[\/]*$/g, '')
    } else {
      return part.trim().replace(/(^[\/]*|[\/]*$)/g, '')
    }
  }).filter(x=>x.length).join('/')
}
  • build_path("http://google.com/", "my", "path")will return "http://google.com/my/path"
  • build_path("//a", "", "/", "/b/")will return "//a/b"
  • build_path()will return ""
  • build_path("http://google.com/", "my", "path")将返回 "http://google.com/my/path"
  • build_path("//a", "", "/", "/b/")将返回 "//a/b"
  • build_path()将返回 ""

Note that this regex strips trailing slashes. Sometimes a trailing slash carries semantic meaning (e.g. denoting a directory rather than a file), and that distinction will be lost here.

请注意,此正则表达式会去除尾部斜杠。有时尾部斜杠带有语义(例如表示目录而不是文件),而这种区别在这里将丢失。

回答by anneb

The accepted answer doesn't work for URLs, it removes the double slash after the protocol
https://hostnamebecomes https:/hostname.

接受的答案不适用于 URL,它在协议
https://hostname变为https:/hostname.

Most other answers do not handle the first and last part differently. A slash at the beginning or end should not be removed, it would change the meaning (relative/absolute) (file/directory) of the joined path.

大多数其他答案不会以不同的方式处理第一部分和最后一部分。不应删除开头或结尾的斜杠,它会改变连接路径的含义(相对/绝对)(文件/目录)。

Below is a modified version of the accepted answer:

以下是已接受答案的修改版本:

function pathJoin(parts, sep){
    const separator = sep || '/';
    parts = parts.map((part, index)=>{
        if (index) {
            part = part.replace(new RegExp('^' + separator), '');
        }
        if (index !== parts.length - 1) {
            part = part.replace(new RegExp(separator + '$'), '');
        }
        return part;
    })
    return parts.join(separator);
 }

usage:

用法:

console.log(pathJoin(['https://', 'hostname', 'path/'])); // 'https://hostname/path/'
console.log(pathJoin(['relative/', 'path', 'to/dir/']));  // 'relative/path/to/dir/'
console.log(pathJoin(['/absolute/', 'path', 'to/file'])); // '/absolute/path/to/file'

https://jsfiddle.net/tdsLencu/

https://jsfiddle.net/tdsLencu/

回答by Nikos M.

You may find the code on this gist "Simple path join and dirname functions for generic javascript"useful (i.e both in node and browser)

您可能会发现此要点上的代码“通用 javascript 的简单路径连接和目录名函数”很有用(即在节点和浏览器中)

// Joins path segments.  Preserves initial "/" and resolves ".." and "."
// Does not support using ".." to go above/outside the root.
// This means that join("foo", "../../bar") will not resolve to "../bar"
function join(/* path segments */) {
  // Split the inputs into a list of path commands.
  var parts = [];
  for (var i = 0, l = arguments.length; i < l; i++) {
    parts = parts.concat(arguments[i].split("/"));
  }
  // Interpret the path commands to get the new resolved path.
  var newParts = [];
  for (i = 0, l = parts.length; i < l; i++) {
    var part = parts[i];
    // Remove leading and trailing slashes
    // Also remove "." segments
    if (!part || part === ".") continue;
    // Interpret ".." to pop the last segment
    if (part === "..") newParts.pop();
    // Push new path segments.
    else newParts.push(part);
  }
  // Preserve the initial slash if there was one.
  if (parts[0] === "") newParts.unshift("");
  // Turn back into a single string path.
  return newParts.join("/") || (newParts.length ? "/" : ".");
}

// A simple function to get the dirname of a path
// Trailing slashes are ignored. Leading slash is preserved.
function dirname(path) {
  return join(path, "..");
}

Notesimilar implementations (which may be transformed to js code as well) exist for php here

注意php here存在类似的实现(也可以转换为 js 代码)

回答by Berty

This one makes sure it works with http:// links without removing the double slash. It trims the slashes at the beginning and end of each part. Then joins them seperated by '/'

这个确保它可以与 http:// 链接一起使用,而无需删除双斜杠。它修剪每个部分开头和结尾的斜线。然后加入它们,以 '/' 分隔

/**
 * Joins 2 paths together and makes sure there aren't any duplicate seperators
 * @param parts the parts of the url to join. eg: ['http://google.com/', '/my-custom/path/']
 * @param separator The separator for the path, defaults to '/'
 * @returns {string} The combined path
 */
function joinPaths(parts, separator) {
  return parts.map(function(part) { return part.trim().replace(/(^[\/]*|[\/]*$)/g, ''); }).join(separator || '/');
}

回答by ahmed

My approach to solve this problem:

我解决这个问题的方法:

var path = ['a/','b'].map(function (i) {
    return i.replace(/(^\/|\/$)/, '');
}).join('/');

Second method:

第二种方法:

var path = ['a/','b'].join('/').replace(/\/{2,}/, '/')

回答by Luc Kim-Hall

There is not, however it is pretty easy to implement. This could also be solved with a regex but its not too bad without one.

没有,但是很容易实现。这也可以用正则表达式解决,但没有正则表达式也不错。

var pathJoin = function(pathArr){
    return pathArr.map(function(path){
        if(path[0] === "/"){
            path = path.slice(1);        
        }
        if(path[path.length - 1] === "/"){
            path = path.slice(0, path.length - 1);   
        }
        return path;     
    }).join("/");
}

http://jsfiddle.net/swoogie/gfy50cm1/

http://jsfiddle.net/swoogie/gfy50cm1/