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

时间:2015-04-24 18:39:11

标签: javascript python

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

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

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

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

修改 应该指明我正在做这个客户端。

10 个答案:

答案 0 :(得分:12)

使用path模块。 path.join正是您正在寻找的。 From the docs

  

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   将所有参数加在一起并规范化生成的路径。

     

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

     

示例:

style="display:block;"

修改

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

答案 1 :(得分:8)

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

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//'])

答案 2 :(得分:5)

在@ Berty的回复基础上,这个ES6变体会保留所有前导斜杠,与protocol relative url's一起使用(如//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")将返回"http://google.com/my/path"
  • build_path("//a", "", "/", "/b/")将返回"//a/b"
  • build_path()将返回""

答案 3 :(得分:2)

您可能会发现此gist "Simple path join and dirname functions for generic 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, "..");
}

注意 php here

存在类似的实现(也可能转换为js代码)

答案 4 :(得分:1)

我解决这个问题的方法:

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

第二种方法:

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

答案 5 :(得分:1)

但实际上并不容易实现。这也可以通过正则表达式解决,但没有一个也不会太糟糕。

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/

答案 6 :(得分:1)

这个确保它适用于http://链接而不删除双斜杠。 它修剪了每个部分开头和结尾的斜线。然后将它们加入&#39; /&#39;

/**
 * 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 || '/');
}

答案 7 :(得分:0)

接受的答案不适用于网址,它会删除协议后的双斜杠
ptr + nsize - 1成为https://hostname

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

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

https:/hostname

用法:

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

https://jsfiddle.net/tdsLencu/

答案 8 :(得分:0)

来自MDN文档Path manipulation OS.path

OS.Path.join

加入路径组件。建议使用此文件来获取目录中包含的文件或子目录的路径。

示例:

var tmpDir = OS.Constants.Path.tmpDir;
var path = OS.Path.join(tmpDir, "foo", "bar");

在大多数版本的Unix上将返回“ / tmp / foo / bar”; 在将临时目录放置在C:\ Windows \ Temp的Windows版本上为“ C:\ Windows \ Temp \ foo \ bar”; 等

string join(
  in string path,
  ...in string subpaths
)

参数

  • 路径: 路径
  • 子路径: 零,一个或多个必须附加到路径的路径

返回

连接路径的结果。如果任何子路径是绝对的,则该子路径之前的任何内容都将被忽略。路径可能未标准化。

答案 9 :(得分:0)

以@leo 所做的为基础:

export function buildPath(...args: string[]): string {
  const [first] = args;
  const firstTrimmed = first.trim();
  const result = args
    .map((part) => part.trim())
    .map((part, i) => {
      if (i === 0) {
        return part.replace(/[/]*$/g, '');
      } else {
        return part.replace(/(^[/]*|[/]*$)/g, '');
      }
    })
    .filter((x) => x.length)
    .join('/');

  return firstTrimmed === '/' ? `/${result}` : result;
}

应涵盖以下场景:

  [
    {
      input: ['/'],
      result: '/',
    },
    {
      input: ['/', 'aaa', ':id'],
      result: '/aaa/:id',
    },
    {
      input: ['/bbb', ':id'],
      result: '/bbb/:id',
    },
    {
      input: ['ccc', ':id'],
      result: 'ccc/:id',
    },
    {
      input: ['/', '/', '/', '/ddd/', '/', ':id'],
      result: '/ddd/:id',
    },
    {
      input: ['', '', '', 'eee', '', ':id'],
      result: 'eee/:id',
    },
  ];