Есть ли встроенная функция javascript, похожая на os.path.join?
Есть ли встроенная функция javascript, которая работает аналогично python os.path.join
? Я знаю, что могу присоединиться к строкам следующим образом:
['a', 'b'].join('/')
Проблема заключается в том, что если строки уже содержат ведущий/конечный "/", то они не будут соединены правильно, например:
['a/','b'].join('/')
Edit:
Должен был указать, что я делаю эту клиентскую сторону.
Ответы
Ответ 1
В настоящее время нет встроенного модуля, который будет выполнять соединение, не допуская дублирования разделителей. Если вы хотите лаконично, я просто напишу себе:
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
Используйте модуль path
. path.join
- именно то, что вы ищете. Из документов:
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:
Я предположил, что вы используете Javascript на стороне сервера, например node.js. Если вы хотите использовать его в браузере, вы можете использовать path-browserify.
Ответ 3
Опираясь на ответ @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")
вернет "http://google.com/my/path"
build_path("//a", "", "/", "/b/")
вернет "//a/b"
build_path()
вернет ""
Ответ 4
Вы можете найти полезный код в этом gist "Простые пути для соединения и функции dirname для общего javascript" (т.е. как в node и браузер)
// 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, "..");
}
Примечание аналогичные реализации (которые также могут быть преобразованы в код js) существуют для php здесь
Ответ 5
Принятый ответ не работает для URL, он удаляет двойную косую черту после протокола
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);
}
использование:
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/
Ответ 6
Мой подход к решению этой проблемы:
var path = ['a/','b'].map(function (i) {
return i.replace(/(^\/|\/$)/, '');
}).join('/');
Второй метод:
var path = ['a/','b'].join('/').replace(/\/{2,}/, '/')
Ответ 7
Нет, однако его довольно легко реализовать. Это также можно было бы решить с помощью регулярного выражения, но это было бы неплохо без него.
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/
Ответ 8
Это гарантирует, что он работает с ссылками 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 || '/');
}