Как обрезать расширение файла из строки в JavaScript? - PullRequest
246 голосов
/ 23 ноября 2010

Например, предполагая, что x = filename.jpg, я хочу получить filename, где filename может быть любым именем файла (Предположим, что имя файла содержит только [a-zA-Z0-9-_] для упрощения.).

Я видел x.substring(0, x.indexOf('.jpg')) на DZone Snippets , но не будет ли x.substring(0, x.length-4) работать лучше?Потому что length является свойством и не выполняет проверку символов, тогда как indexOf() является функцией и выполняет проверку символов.

Ответы [ 24 ]

402 голосов
/ 23 ноября 2010

Не уверен, что будет работать быстрее, но это будет более надежно, когда речь идет о расширении, таком как .jpeg или .html

x.replace(/\.[^/.]+$/, "")
172 голосов
/ 24 июля 2015

В node.js имя файла без расширения можно получить следующим образом.

const path = require('path');
var filename = 'hello.html';

path.parse(filename).name; // hello
path.parse(filename).ext;  // .html

Дополнительное объяснение на Node.js документация стр.

132 голосов
/ 23 ноября 2010

Если вы знаете длину расширения, вы можете использовать x.slice(0, -4) (где 4 - три символа расширения и точка).

Если вы не знаете, длина @ регулярное выражение Джона Хартсока было бы правильным подходом.

Если вы не хотите использовать регулярные выражения, вы можете попробовать это (менее производительно):

filename.split('.').slice(0, -1).join('.')

Обратите внимание, что произойдет сбой для файлов без расширения.

112 голосов
/ 23 ноября 2010

x.length-4 учитывает только расширения с 3 символами. Что делать, если у вас есть filename.jpeg или filename.pl?

EDIT:

Чтобы ответить ... конечно, если у вас всегда есть расширение .jpg, x.length-4 будет работать нормально.

Однако, если вы не знаете длину своего расширения, любое из ряда решений лучше / надежнее.

x = x.replace(/\..+$/, '');

OR

x = x.substring(0, x.lastIndexOf('.'));

ИЛИ

x = x.replace(/(.*)\.(.*?)$/, "$1");

ИЛИ (при условии, что имя файла имеет только одну точку)

parts = x.match(/[^\.]+/);
x = parts[0];

ИЛИ (также только с одной точкой)

parts = x.split(".");
x = parts[0];
37 голосов
/ 23 ноября 2010

Возможно, вы можете использовать предположение, что последняя точка будет разделителем расширения.

var x = 'filename.jpg';
var f = x.substr(0, x.lastIndexOf('.'));

Если файл не имеет расширения, он вернет пустую строку.Чтобы исправить это используйте эту функцию

function removeExtension(filename){
    var lastDotPosition = filename.lastIndexOf(".");
    if (lastDotPosition === -1) return filename;
    else return filename.substr(0, lastDotPosition);
}
13 голосов
/ 16 декабря 2015

В версиях Node.js до 0.12.x:

path.basename(filename, path.extname(filename))

Конечно, это также работает в 0.12.x и позже.

11 голосов
/ 17 сентября 2014

Это работает, даже если в строке нет разделителя.

String.prototype.beforeLastIndex = function (delimiter) {
    return this.split(delimiter).slice(0,-1).join(delimiter) || this + ""
}

"image".beforeLastIndex(".") // "image"
"image.jpeg".beforeLastIndex(".") // "image"
"image.second.jpeg".beforeLastIndex(".") // "image.second"
"image.second.third.jpeg".beforeLastIndex(".") // "image.second.third"

Можно также использовать как однострочник:

var filename = "this.is.a.filename.txt";
console.log(filename.split(".").slice(0,-1).join(".") || filename + "");

РЕДАКТИРОВАТЬ: Это более эффективное решение:

String.prototype.beforeLastIndex = function (delimiter) {
    return this.substr(0,this.lastIndexOf(delimiter)) || this + ""
}
8 голосов
/ 24 декабря 2017

Мне нравится этот, потому что это один лайнер, который не слишком трудно читать:

filename.substring(0, filename.lastIndexOf('.')) || filename
7 голосов
/ 08 января 2014

Еще один вкладыш:

x.split(".").slice(0, -1).join(".")
7 голосов
/ 29 ноября 2015

Я не знаю, является ли это допустимым вариантом, но я использую это:

name = filename.split(".");
// trimming with pop()
name.pop();
// getting the name with join()
name.join('.'); // we split by '.' and we join by '.' to restore other eventual points.

Это не просто одна операция, которую я знаю, но, по крайней мере, она всегда должна работать!

ОБНОВЛЕНИЕ: Если вы хотите, чтобы он был лайнером, вы здесь:

(name.split('.').slice(0, -1)).join('.')

...