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.



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.


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(/\.[^/.]+$/, "")

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.


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];

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

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


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 + ""
}

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


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


7

Berikut solusi berbasis regex lain:

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

Ini seharusnya hanya memotong segmen terakhir.


7

Sederhana

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

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(/(\.[^/.]+)+$/, "");


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


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


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.


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

0

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

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

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'


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

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.


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.