Bagaimana cara memotong ekstensi file dari String di JavaScript?

295

Misalnya, dengan asumsi itu x = filename.jpg, saya ingin dapatkan filename, di mana filenamebisa ada nama file apa saja (Mari kita asumsikan nama file hanya berisi [a-zA-Z0-9-_] untuk disederhanakan.).

Saya melihat x.substring(0, x.indexOf('.jpg'))di DZone Snippets , tetapi tidak akan x.substring(0, x.length-4)berkinerja lebih baik? Karena, lengthadalah properti dan tidak melakukan pengecekan karakter sedangkan indexOf()fungsi dan pengecekan karakter.

ma11hew28
sumber
Hampir sama dengan stackoverflow.com/questions/1991608/… . Dan kecuali Anda melakukan banyak hal, khawatir tentang efisiensi adalah Pengoptimalan Dini.
The Archetypal Paul
Di zaman ES6, lihat juga modul Path - jika Anda menggunakan nodejs atau transpilasi yang tepat
Frank Nocke

Jawaban:

173

Jika Anda tahu panjang ekstensi, Anda dapat menggunakan x.slice(0, -4)(di mana 4 adalah tiga karakter dari ekstensi dan titik).

Jika Anda tidak tahu panjang regex @ John Hartsock akan menjadi pendekatan yang tepat.

Jika Anda lebih suka tidak menggunakan ekspresi reguler, Anda dapat mencoba ini (lebih sedikit performan):

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

Perhatikan bahwa itu akan gagal pada file tanpa ekstensi.

Marek Sapota
sumber
Saya suka solusi ini yang terbaik. Ini bersih, dan saya bisa menggunakannya karena saya tahu ekstensi file selalu .jpg. Saya mencari sesuatu seperti Ruby x[0..-5], dan x.slice(0, -4)terlihat hebat! Terima kasih! Dan terima kasih kepada semua orang untuk semua alternatif kuat lainnya yang disediakan!
ma11hew28
22
ini bukan solusi optimal, silakan periksa solusi lain di bawah ini.
bunjeeb
8
Dan jika Anda tidak 100% yakin tentang panjang ekstensi, maka jangan lakukan ini: "picture.jpeg".slice(0, -4)-> "gambar."
basic6
13
Ini solusi berbahaya, karena Anda tidak tahu panjang formatnya.
Coder
"Jika Anda tahu panjang ekstensi" Sudah puluhan tahun sejak ini adalah asumsi yang dapat diterima. Jangan gunakan ini lagi.
Alexander - Pasang kembali Monica
453

Tidak yakin apa yang akan bekerja lebih cepat tetapi ini akan lebih dapat diandalkan ketika datang ke ekstensi seperti .jpegatau.html

x.replace(/\.[^/.]+$/, "")
John Hartsock
sumber
15
Anda mungkin ingin juga melarang / sebagai pemisah jalur, sehingga regexp adalah / \.[^
+$/
Ini berfungsi untuk setiap panjang ekstensi file (.txt atau .html atau .htaccess) dan juga memungkinkan nama file mengandung karakter periode (.) Tambahan. Itu tidak akan menangani mis .tar.gz karena ekstensi itu sendiri berisi titik. Itu lebih umum untuk nama file mengandung periode tambahan dari ekstensi file. Terima kasih!
Steve Seeger
2
@ Vik Ada perbedaan antara 'jawaban yang benar' dan jawaban yang diterima. Jawaban yang diterima hanyalah jawaban yang bermanfaat bagi orang yang mengajukan pertanyaan.
Steven
4
Saya kira mungkin ada masalah dengan platform Windows karena mungkin ada garis miring. Jadi regexp seharusnya menjadi /\.[^/\\.
Alex Chuev
1
@ ElgsQianChen di sini adalah alat yang hebat bagi Anda untuk membantu menjawab pertanyaan Anda regexr.com
John Hartsock
281

Di node.js , nama file tanpa ekstensi dapat diperoleh sebagai berikut.

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

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

Penjelasan lebih lanjut di halaman dokumentasi Node.js.

Jibesh Patra
sumber
2
Apa yang Anda bicarakan @kaasdude .... metode ini secara efektif menghapus ekstensi pada node., Tidak yakin apa yang ingin Anda ungkapkan, tetapi metode ini berfungsi dengan baik.
Erick
1
Jawaban ini cukup terbatas untuk node sisi server. Jika Anda mencoba menggunakan ini dalam kode reaksi, sepertinya tidak mengimpor.
Charlie
1
jika Anda ingin menghapus ekstensi dari jalur termasuk direktori, Anda dapat melakukan var parsed = path.parse(filename)diikuti oleh path.join(parsed.dir, parsed.name).
Jespertheend
Kemungkinan lain adalah let base = path.basename( file_path, path.extname( file_path ) ).
bicarlsen
116

x.length-4hanya menyumbang ekstensi 3 karakter. Bagaimana jika Anda punya filename.jpegatau filename.pl?

EDIT:

Untuk menjawab ... tentu saja, jika Anda selalu memiliki ekstensi .jpg, x.length-4akan bekerja dengan baik.

Namun, jika Anda tidak tahu panjang ekstensi Anda, salah satu dari sejumlah solusi lebih baik / lebih kuat.

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

ATAU

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

ATAU

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

ATAU (dengan asumsi nama file hanya memiliki satu titik)

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

ATAU (juga dengan hanya satu titik)

parts = x.split(".");
x = parts[0];
Jeff B
sumber
12
?? Anda dapat memiliki nama file, ex: "summer.family.jpg" dalam case split ('.') [0] hanya akan mengembalikan sebagian nama file. Saya akan menghapus yang dari jawaban, atau jelas menyatakan di bawah masalah untuk contoh itu. @basarat ...
Roko C. Buljan
Sesuatu yang sering saya lakukan mengenai pemisahan bagian:var parts = full_file.split("."); var ext = parts[parts.length-1]; var file = parts.splice(0,parts.length-1).join(".");
radicand
x.split (".") seharusnya tidak dianggap sebagai jawaban. Saya tahu saya menggunakan '.' di hampir semua konvensi penamaan file saya, yaitu 'survey.controller.js', atau 'my.family.jpg'.
Lee Brindley
@ Lee2808: Oleh karena itu peringatan hanya satu titik. Ini hanya dimaksudkan untuk menunjukkan bahwa ada sejumlah pendekatan, tergantung pada aplikasinya. Saya pasti akan menggunakan salah satu metode lain di hampir semua kasus.
Jeff B
x = x.substr(0, x.lastIndexOf('.'));- Anda mungkin bermaksud x = x.substring(0, x.lastIndexOf('.'));?
Dziad Borowy
39

Anda mungkin dapat menggunakan asumsi bahwa titik terakhir akan menjadi pembatas ekstensi.

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

Jika file tidak memiliki ekstensi, itu akan mengembalikan string kosong. Untuk memperbaikinya gunakan fungsi ini

function removeExtension(filename){
    var lastDotPosition = filename.lastIndexOf(".");
    if (lastDotPosition === -1) return filename;
    else return filename.substr(0, lastDotPosition);
}
Martin Algesten
sumber
Peringatan, ini gagal jika tidak ada ekstensi nama file. Anda ditinggalkan dengan string kosong.
Brad
18
Versi lebih pendek yang memperhitungkan tanpa titik. var f = x.substr(0, x.lastIndexOf('.')) || x;Ini berfungsi karena string kosong adalah falsy, oleh karena itu mengembalikan x.
Jonathan Rowny
22

Saya suka yang ini karena ini adalah liner satu yang tidak terlalu sulit dibaca:

filename.substring(0, filename.lastIndexOf('.')) || filename
jakubiszon
sumber
17

Dalam versi Node.js sebelum 0.12.x:

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

Tentu saja ini juga berfungsi di 0.12.x dan yang lebih baru.

blah238
sumber
The path.parseJawabannya sederhana.
Dan Dascalescu
12

Ini berfungsi, bahkan ketika pembatas tidak ada dalam string.

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"

Dapat juga digunakan sebagai one-liner seperti ini:

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

EDIT: Ini adalah solusi yang lebih efisien:

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

Saya tidak tahu apakah ini opsi yang valid tetapi saya menggunakan ini:

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.

Bukan hanya satu operasi yang saya tahu, tetapi setidaknya itu harus selalu berhasil!

UPDATE: Jika Anda ingin oneliner, di sini Anda berada:

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

Giacomo Cerquone
sumber
1
Seharusnya bukan name.join ('') tetapi name.join ('.'). Anda membagi demi titik tetapi bergabung dengan koma, jadi hello.name.txtkembalihello, name
Evil
7

Satu kalimat lagi:

x.split(".").slice(0, -1).join(".")
Jacob Bundgaard
sumber
7

Berikut solusi berbasis regex lain:

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

Ini seharusnya hanya memotong segmen terakhir.

Chad Johnson
sumber
7

Sederhana

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

Jawaban yang diterima hanya menghapus bagian ekstensi terakhir ( .jpeg), yang mungkin merupakan pilihan yang baik dalam kebanyakan kasus.

Saya pernah harus menghapus semua ekstensi ( .tar.gz) dan nama file dibatasi untuk tidak mengandung titik (jadi 2015-01-01.backup.tartidak akan menjadi masalah):

var name = "2015-01-01_backup.tar.gz";
name.replace(/(\.[^/.]+)+$/, "");
basic6
sumber
4
var fileName = "something.extension";
fileName.slice(0, -path.extname(fileName).length) // === "something"
Yas
sumber
Ini adalah satu-satunya metode sejauh ini yang bekerja untuk jalur penuh: path/name.ext-> paht/namebukan hanya kembali name, tapi saya lebih suka melakukannya dengan fs.parsemeskipun sedikit lebih verbose: stackoverflow.com/a/59576950/895245
Ciro Santilli 郝海东 冠状 病六四 事件 法轮功
3

Jika Anda harus memproses variabel yang berisi path lengkap (mis .:) thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg"dan Anda ingin mengembalikan hanya "nama file" Anda dapat menggunakan:

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

hasilnya adalah theName == "filename" ;

Untuk mencobanya tulis perintah berikut ke jendela konsol debugger krom Anda: window.location.pathname.split("/").slice(-1).join().split(".").shift()

Jika Anda harus memproses hanya nama file dan ekstensinya (mis .:) theNameWithExt = "filename.jpg":

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

hasilnya adalah theName == "filename" , sama seperti di atas;

Catatan:

  1. Yang pertama sedikit lebih lambat karena melakukan lebih banyak operasi; tetapi berfungsi dalam kedua kasus, dengan kata lain dapat mengekstrak nama file tanpa ekstensi dari string yang diberikan yang berisi path atau nama file dengan ex. Sedangkan yang kedua hanya berfungsi jika variabel yang diberikan berisi nama file dengan ext seperti namafile.ext tetapi sedikit lebih cepat.
  2. Kedua solusi berfungsi untuk file lokal dan server;

Tapi saya tidak bisa mengatakan apa-apa tentang perbandingan kinerja dengan jawaban lain atau untuk kompatibilitas browser atau OS.

cuplikan 1 yang berfungsi: jalur lengkap

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

cuplikan kerja 2: nama file dengan ekstensi

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

cuplikan kerja 2: nama file dengan ekstensi ganda

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

willy wonka
sumber
3

Meskipun sudah agak terlambat, saya akan menambahkan pendekatan lain untuk mendapatkan nama file tanpa ekstensi menggunakan JS- tua biasa

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

Munim Dibosh
sumber
atau path.split('.').pop()untuk satu ekstensi file bagian
mixdev
Dia sebenarnya mencoba untuk mendapatkan nama file, bukan ekstensi!
Munim Dibosh
3

Node.js menghapus ekstensi dari direktori pemelihara jalur penuh

https://stackoverflow.com/a/31615711/895245 misalnya lakukan path/hello.html-> hello, tetapi jika Anda mau path/hello.html-> path/hello, Anda dapat menggunakan ini:

#!/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));

direktori keluaran juga:

path/hello

https://stackoverflow.com/a/36099196/895245 juga mencapai ini, tapi saya menemukan pendekatan ini sedikit lebih menyenangkan secara semantik.

Diuji dalam Node.js v10.15.2.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
0

Di sinilah ekspresi reguler berguna! .replace()Metode Javascript akan mengambil ekspresi reguler, dan Anda dapat menggunakannya untuk mencapai apa yang Anda inginkan:

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

Satu liner lain - kami anggap file kami adalah gambar jpg >> ex: var yourStr = 'test.jpg';

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

Anda bisa menggunakannya pathuntuk bermanuver.

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

Keluaran

> filePath
'/User/HELLO/WORLD/FILENAME'
> fileName
'FILENAME'
> MYPATH
'/User/HELLO/WORLD/FILENAME.js'
Alan Dong
sumber
0
x.slice(0, -(x.split('.').pop().length + 1));
ishandutta2007
sumber
0

Ini adalah kode yang saya gunakan untuk menghapus ekstensi dari nama file, tanpa menggunakan regex atau indexOf (indexOf tidak didukung di IE8). Diasumsikan bahwa ekstensi adalah teks apa pun setelah 'terakhir'. karakter.

Ini berfungsi untuk:

  • file tanpa ekstensi: "myletter"
  • file dengan '.' dalam nama: "my.letter.txt"
  • panjang ekstensi file tidak diketahui: "my.letter.html"

Ini kodenya:

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;
}
Otak Kecil
sumber
gagal dengan hello.tar.gz, output hellotar.
Asif Ali
#AsifAli terima kasih benar, saya lupa membaca ekstensi file. Saya sudah memperbarui jawabannya, saya harap ini berhasil sekarang.
Otak Kecil
-3

Saya akan menggunakan sesuatu seperti x.substring (0, x.lastIndexOf ('.')). Jika Anda ingin kinerja, jangan gunakan javascript sama sekali :-p Tidak, satu pernyataan lagi benar-benar tidak masalah untuk 99,99999% dari semua tujuan.

Lucas Moeskops
sumber
2
"Jika Anda ingin kinerja, jangan gunakan javascript sama sekali" - Apa lagi yang Anda sarankan untuk digunakan dalam aplikasi web ..?
TJ
Dia tidak menyebutkan aplikasi web.
Lucas Moeskops
1
Pertanyaan ini diajukan dan jawabannya diposting pada 2010, 7 tahun yang lalu, dan JavaScript cukup banyak digunakan hanya dalam aplikasi web. (Node baru saja lahir, ia bahkan tidak memiliki panduan atau NPM pada waktu itu)
TJ
;-) Namun, jika kinerja penting pada tugas-tugas seperti ini, Anda dapat mempertimbangkan melakukan ini di backend dan memproses hasilnya di frontend.
Lucas Moeskops