Як обрізати розширення файлу з рядка в JavaScript?


295

Наприклад, припускаючи, що 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()як це функція і робить перевірку символів.



Приблизно те саме, що stackoverflow.com/questions/1991608/… . І якщо ви не зробите з них багато, переживаючи про ефективність, це передчасна оптимізація.
Архетипний Павло

У віці ES6 також дивіться модуль Path - якщо ви використовуєте nodejs або належну транспіляцію
Frank Nocke

Відповіді:


173

Якщо ви знаєте довжину розширення, ви можете використовувати x.slice(0, -4)(де 4 - це три символи розширення та крапка).

Якщо ви не знаєте довжину @ Джона Харцока, правильний підхід був би.

Якщо ви не бажаєте використовувати регулярні вирази, ви можете спробувати це (менш ефективний):

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

Зауважте, що він не вийде з файлів без розширення.


Мені подобається це рішення найкраще. Це чисто, і я можу його використовувати, бо знаю, що розширення файлу завжди .jpg. Я шукав щось на кшталт Рубі x[0..-5], і x.slice(0, -4)виглядає чудово! Дякую! І дякую всім іншим за всі інші надійні альтернативи!
ma11hew28

22
це не оптимальне рішення, будь ласка, перевірте інші рішення нижче.
bunjeeb

8
І якщо ви не впевнені на 100% у довжині розширення, тоді не робіть цього: "picture.jpeg".slice(0, -4)-> "картинка".
базовий6

13
Це небезпечне рішення, оскільки ви дійсно не знаєте довжину формату.
Кодер

"Якщо ви знаєте тривалість розширення" Минуло десятиліття, оскільки це було прийнятним припущенням. Більше не використовуйте це.
Олександр - Відновіть Моніку

453

Не впевнений, що буде працювати швидше, але це було б більш надійно, якщо мова йде про розширення типу .jpegабо.html

x.replace(/\.[^/.]+$/, "")

15
Ви, ймовірно, хочете також заборонити / як роздільник шляхів, тому regexp є /\. evidence^
Sense+

Це працює для будь-якої довжини розширення файлу (.txt або .html або .htaccess), а також дозволяє імені файлу містити додаткові символи періоду (.). Він не оброблятиметься, наприклад, .tar.gz через розширення, що містить період. Частіше ім'я файлу містить додаткові періоди, ніж розширення. Дякую!
Стів Зеєгер

2
@Vik Існує різниця між правильною відповіддю та прийнятою відповіддю. Прийнята відповідь - це лише відповідь, яка була корисною для того, хто задав питання.
Стівен

4
Я припускаю, що з платформою Windows можуть виникнути проблеми, оскільки можуть бути зворотні косої риски. Таким чином, регулярний вираз повинен бути /\. evidence^/\\.Sense+$/.
Олексій Чуєв

1
@ElgsQianChen - це чудовий інструмент, який допоможе вам відповісти на запитання regexr.com
John Hartsock

281

У node.js ім'я файлу без розширення можна отримати наступним чином.

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

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

Подальше пояснення на сторінці документації Node.js.


2
Що ви говорите про @kaasdude .... цей метод ефективно видаляє розширення на вузлі. Не впевнений, що ви хотіли висловити, але цей метод працює перлами.
Ерік

1
Ця відповідь досить обмежена на серверному вузлі. Якщо ви спробуєте використати це у коді реагування, він, здається, не імпортується.
Чарлі

1
якщо ви хочете видалити розширення зі шляху, що включає каталоги, ви можете зробити var parsed = path.parse(filename)його path.join(parsed.dir, parsed.name).
Jespertheend

Інша можливість є let base = path.basename( file_path, path.extname( file_path ) ).
bicarlsen

116

x.length-4нараховує лише розширення з 3 символів. Що робити, якщо у вас є filename.jpegабо filename.pl?

Редагувати:

Відповісти ... звичайно, якщо у вас завжди є розширення .jpg, x.length-4працювало б чудово.

Однак якщо ви не знаєте довжину розширення, будь-яке з ряду рішень є кращим / надійнішим.

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

АБО

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

АБО

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

АБО (з назвою файлу припущення є лише одна крапка)

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

АБО (також із лише однією крапкою)

parts = x.split(".");
x = parts[0];

12
?? Ви можете мати ім'я файлу ex: "summer.family.jpg" у цьому випадку split ('.') [0] поверне лише часткове ім'я файлу. Я б видалив цю відповідь з відповіді або чітко зазначив під питанням для цього прикладу. @basarat ...
Roko C. Buljan

Щось я часто роблю щодо розбиття на частину:var parts = full_file.split("."); var ext = parts[parts.length-1]; var file = parts.splice(0,parts.length-1).join(".");
radicand

x.split (".") навіть не слід вважати відповіддю. Я знаю, що використовую '.' майже у всіх конвенціях про іменування моїх файлів, наприклад, 'survey.controller.js', або 'my.family.jpg'.
Лі Бріндлі

@ Lee2808: Звідси попередження лише про одну крапку. Це просто покликане показати, що існує ряд підходів, залежно від програми. Я, звичайно, використовував би один із інших методів майже у всіх випадках.
Джефф Б

x = x.substr(0, x.lastIndexOf('.'));- ти мабуть мав на увазі x = x.substring(0, x.lastIndexOf('.'));?
Dziad Borowy

39

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

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

Попередження, це не вдається, якщо не відбувається розширення імені файлу. Вам залишається порожня рядок.
Бред

18
Коротша версія, що не містить крапок. var f = x.substr(0, x.lastIndexOf('.')) || x;Це працює, тому що порожній рядок є хибним, тому він повертає x.
Джонатан Роуні

22

Мені це подобається, тому що це один вкладиш, який не так важко читати:

filename.substring(0, filename.lastIndexOf('.')) || filename


12

Це працює, навіть якщо роздільник не є в рядку.

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 + "");

EDIT: Це більш ефективне рішення:

String.prototype.beforeLastIndex = function (delimiter) {
    return this.substr(0,this.lastIndexOf(delimiter)) || this + ""
}

10

Я не знаю, чи це допустимий варіант, але я використовую це:

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('.')


1
Це має бути не name.join (''), а name.join ('.'). Ви розділяєте крапку, але приєднуєтесь комою, тому hello.name.txtповертаєтьсяhello, name
Зло


7

Ось ще одне рішення на основі регулярних виразів:

filename.replace(/\.[^.$]+$/, '');

Це повинно рубати лише останній сегмент.


7

Простий:

var n = str.lastIndexOf(".");
return n > -1 ? str.substr(0, n) : str;

6

Прийнята відповідь знімає лише останню частину розширення ( .jpeg), що може бути хорошим вибором у більшості випадків.

Мені колись довелося викреслити всі розширення ( .tar.gz), імена файлів обмежувались, щоб вони не містили крапок (так що 2015-01-01.backup.tarце не буде проблемою):

var name = "2015-01-01_backup.tar.gz";
name.replace(/(\.[^/.]+)+$/, "");

4
var fileName = "something.extension";
fileName.slice(0, -path.extname(fileName).length) // === "something"

Це єдиний метод , який до цих пір працює для повних шляхів: path/name.ext-> paht/nameзамість того , щоб просто повернення name, але я волів би зробити з з , fs.parseхоча це трохи більш багатослівний: stackoverflow.com/a/59576950/895245
Чіро Сантіллі郝海东冠状病六四 事件 法轮功

3

Якщо вам доведеться обробити змінну, яка містить повний шлях (напр .:), thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg"і ви хочете повернути просто "ім'я файлу", ви можете використовувати:

theName = thePath.split("/").slice(-1).join().split(".").shift();

результатом буде theName == "ім'я файлу" ;

Щоб спробувати це, напишіть таку команду у вікно консолі хромованого налагоджувача: window.location.pathname.split("/").slice(-1).join().split(".").shift()

Якщо вам потрібно обробити лише ім'я файлу та його розширення (напр .:) theNameWithExt = "filename.jpg":

theName = theNameWithExt.split(".").shift();

результатом буде theName == "ім'я файлу" , таким же, як вище;

Примітки:

  1. Перший - трохи повільніше, тому що виконує більше операцій; але працює в обох випадках, інакше кажучи, він може витягувати ім'я файлу без розширення із заданої рядки, що містить шлях або ім'я файлу з колишнім. Хоча друга працює лише в тому випадку, якщо дана змінна містить ім'я файлу з ext як filename.ext, але трохи швидше.
  2. Обидва рішення працюють як для локальних, так і для серверних файлів;

Але я нічого не можу сказати ні про порівняння продуктивності з іншими відповідями, ні про сумісність браузера чи ОС.

робочий фрагмент 1: повний шлях

var thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg";
theName = thePath.split("/").slice(-1).join().split(".").shift();
alert(theName);
  

робочий фрагмент 2: ім'я файлу з розширенням

var theNameWithExt = "filename.jpg";
theName = theNameWithExt.split("/").slice(-1).join().split(".").shift();
alert(theName);
  

робочий фрагмент 2: ім'я файлу з подвійним розширенням

var theNameWithExt = "filename.tar.gz";
theName = theNameWithExt.split("/").slice(-1).join().split(".").shift();
alert(theName);
  


3

Хоча це досить пізно, я додам інший підхід, щоб отримати ім'я файлу без розширення, використовуючи звичайний старий JS-

path.replace(path.substr(path.lastIndexOf('.')), '')


або path.split('.').pop()для однієї частини розширення файлу
mixdev

Він насправді намагався отримати ім’я файлу, а не розширення!
Мунім Дібош

3

Node.js видаліть розширення з повного каталогу зберігання шляху

https://stackoverflow.com/a/31615711/895245, наприклад, зробив path/hello.html-> hello, але якщо ви хочете path/hello.html-> path/hello, ви можете скористатися цим:

#!/usr/bin/env node
const path = require('path');
const filename = 'path/hello.html';
const filename_parsed = path.parse(filename);
console.log(path.join(filename_parsed.dir, filename_parsed.name));

також вихідний каталог:

path/hello

https://stackoverflow.com/a/36099196/895245 також досягає цього, але я вважаю такий підхід трохи більш семантично приємним.

Тестовано в Node.js v10.15.2.


0

Ось тут корисні регулярні вирази! .replace()Метод Javascript буде приймати регулярний вираз, і ви можете використовувати це для досягнення того, що ви хочете:

// assuming var x = filename.jpg or some extension
x = x.replace(/(.*)\.[^.]+$/, "$1");

0

Ще один вкладиш - ми припускаємо, що наш файл - це jpg-зображення >> ex: var yourStr = 'test.jpg';

    yourStr = yourStr.slice(0, -4); // 'test'

0

Ви можете використовувати pathдля маневру.

var MYPATH = '/User/HELLO/WORLD/FILENAME.js';
var MYEXT = '.js';
var fileName = path.basename(MYPATH, MYEXT);
var filePath = path.dirname(MYPATH) + '/' + fileName;

Вихідні дані

> filePath
'/User/HELLO/WORLD/FILENAME'
> fileName
'FILENAME'
> MYPATH
'/User/HELLO/WORLD/FILENAME.js'


0

Це код, який я використовую для видалення розширення з імені файлу, не використовуючи ні регулярного вираження, ні indexOf (indexOf не підтримується в IE8). Він передбачає, що розширенням є будь-який текст після останнього "." характер.

Він працює для:

  • файли без розширення: "myletter"
  • файли з '.' в назві: "my.letter.txt"
  • невідома довжина розширення файлу: "my.letter.html"

Ось код:

var filename = "my.letter.txt" // some filename

var substrings = filename.split('.'); // split the string at '.'
if (substrings.length == 1)
{
  return filename; // there was no file extension, file was something like 'myfile'
}
else
{
  var ext = substrings.pop(); // remove the last element
  var name = substrings.join(""); // rejoin the remaining elements without separator
  name = ([name, ext]).join("."); // readd the extension
  return name;
}

не вдається hello.tar.gz, вихід є hellotar.
Асиф Алі

#AsifAli дякую, що ви праві, я забув прочитати розширення файлу. Я оновив відповідь, сподіваюся, вона працює зараз.
Маленький мозок

-3

Я б використав щось на кшталт x.substring (0, x.lastIndexOf ('.')). Якщо ви збираєтеся на продуктивність, взагалі не заходьте на javascript :-p Ні, ще одне твердження насправді не має значення для 99,99999% усіх цілей.


2
"Якщо ви збираєтеся на продуктивність, взагалі не переходьте на javascript" - Що ще ви пропонуєте використовувати у веб-програмах ..?
TJ

Він не згадує веб-додатки.
Лукас Moeskops

1
Це питання було задано, і відповідь було розміщено в 2010 році, 7 років тому, а JavaScript в значній мірі використовувався лише у веб-додатках. (Вузол щойно народився, у нього навіть тоді не було керівництва чи НПМ)
TJ

;-) Однак, якщо продуктивність має значення для таких завдань, ви можете розглянути можливість цього робити в бекенд і обробити результати на фронтенді.
Лукас Moeskops
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.