Làm cách nào để cắt phần mở rộng tệp từ Chuỗi trong JavaScript?


295

Ví dụ: giả sử rằng x = filename.jpgtôi muốn lấy filename, nơi filenamecó thể là bất kỳ tên tệp nào (Giả sử tên tệp chỉ chứa [a-zA-Z0-9-_] để đơn giản hóa.).

Tôi đã thấy x.substring(0, x.indexOf('.jpg'))trên DZone Snippets , nhưng sẽ không x.substring(0, x.length-4)hoạt động tốt hơn? Bởi vì, lengthlà một thuộc tính và không thực hiện kiểm tra ký tự trong khi đó indexOf()là một chức năng và kiểm tra ký tự.



Khá giống với stackoverflow.com/questions/1991608/ . Và trừ khi bạn thực hiện một trong số rất nhiều trong số này, lo lắng về hiệu quả là Tối ưu hóa sớm.
Archetypal Paul

Trong thời đại ES6, cũng thấy mô-đun Đường dẫn - trong trường hợp bạn đang sử dụng nodejs hoặc dịch chuyển đúng
Frank Nocke

Câu trả lời:


173

Nếu bạn biết độ dài của tiện ích mở rộng, bạn có thể sử dụng x.slice(0, -4)(trong đó 4 là ba ký tự của tiện ích mở rộng và dấu chấm).

Nếu bạn không biết độ dài @John Hartsock regex sẽ là phương pháp phù hợp.

Nếu bạn không muốn sử dụng các biểu thức thông thường, bạn có thể thử cách này (ít hiệu suất hơn):

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

Lưu ý rằng nó sẽ thất bại trên các tập tin mà không có phần mở rộng.


Tôi thích giải pháp này tốt nhất. Nó sạch và tôi có thể sử dụng nó vì tôi biết phần mở rộng tập tin luôn luôn .jpg. Tôi đang tìm kiếm thứ gì đó giống như của Ruby x[0..-5], và x.slice(0, -4)trông thật tuyệt! Cảm ơn! Và cảm ơn bạn cho tất cả những người khác cho tất cả các lựa chọn thay thế mạnh mẽ khác được cung cấp!
ma11hew28

22
Đây không phải là giải pháp tối ưu, vui lòng kiểm tra các giải pháp khác bên dưới.
bunjeeb

8
Và nếu bạn không chắc chắn 100% về độ dài của tiện ích mở rộng, thì đừng như vậy: "picture.jpeg".slice(0, -4)-> "hình ảnh."
basic6

13
Đây là giải pháp nguy hiểm, vì bạn không thực sự biết độ dài của định dạng.
Coder

"Nếu bạn biết độ dài của phần mở rộng" Đã hàng thập kỷ vì đây là một giả định có thể chấp nhận được. Đừng dùng cái này nữa.
Alexander - Tái lập Monica

453

Không chắc chắn những gì sẽ thực hiện nhanh hơn nhưng điều này sẽ đáng tin cậy hơn khi nói đến phần mở rộng như .jpeghoặc.html

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

15
Có lẽ bạn cũng muốn không cho phép / làm dấu phân cách đường dẫn, do đó, biểu thức chính quy là /\.[ ^ /. [+ $ /
gsnedder

Điều này hoạt động cho bất kỳ độ dài của phần mở rộng tệp (.txt hoặc .html hoặc .htaccess) và cũng cho phép tên tệp chứa các ký tự dấu chấm (.) Bổ sung. Nó sẽ không xử lý ví dụ .tar.gz do phần mở rộng có chứa một khoảng thời gian. Tên tệp phổ biến hơn chứa các khoảng thời gian bổ sung hơn là phần mở rộng tệp. Cảm ơn!
Steve Seeger

2
@Vik Có sự khác biệt giữa 'câu trả lời đúng' và câu trả lời được chấp nhận. Một câu trả lời được chấp nhận chỉ là câu trả lời hữu ích cho người đặt câu hỏi.
Steven

4
Tôi cho rằng có thể có vấn đề với nền tảng Windows vì có thể có dấu gạch chéo ngược. Vì vậy, biểu thức chính quy phải là /\.[ucci/\\.[+$/.
Alex Chuev

1
@ElgsQianChen đây là một công cụ tuyệt vời để bạn giúp trả lời câu hỏi của bạn regexr.com
John Hartsock

281

Trong node.js , tên của tệp không có phần mở rộng có thể được lấy như sau.

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

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

Giải thích thêm tại trang tài liệu Node.js.


2
Những gì bạn đang nói về @kaasdude .... phương pháp này có hiệu quả loại bỏ phần mở rộng trên nút., Không chắc chắn những gì bạn muốn thể hiện, nhưng phương pháp này hoạt động ngọc trai.
Erick

1
Câu trả lời này khá hạn chế đối với nút phía máy chủ. Nếu bạn cố gắng sử dụng mã này trong mã phản ứng, nó dường như không nhập.
Charlie

1
nếu bạn muốn xóa tiện ích mở rộng khỏi đường dẫn bao gồm các thư mục, bạn có thể thực hiện var parsed = path.parse(filename)theo sau path.join(parsed.dir, parsed.name).
Jespertheend

Một khả năng khác là let base = path.basename( file_path, path.extname( file_path ) ).
bicarlsen

116

x.length-4chỉ chiếm phần mở rộng 3 ký tự. Nếu bạn có filename.jpeghoặc filename.pl?

BIÊN TẬP:

Để trả lời ... chắc chắn, nếu bạn luôn có một phần mở rộng .jpg, x.length-4sẽ hoạt động tốt.

Tuy nhiên, nếu bạn không biết độ dài của tiện ích mở rộng, bất kỳ giải pháp nào cũng tốt hơn / mạnh mẽ hơn.

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

HOẶC LÀ

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

HOẶC LÀ

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

HOẶC (với tên tệp giả định chỉ có một dấu chấm)

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

HOẶC (cũng chỉ có một dấu chấm)

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

12
?? Bạn có thể có một tên tệp ex: "summer.family.jpg" trong trường hợp đó được chia ('.') [0] sẽ chỉ trả lại một tên tệp một phần. Tôi sẽ loại bỏ câu hỏi đó khỏi câu trả lời, hoặc nêu rõ bên dưới vấn đề cho ví dụ đó. @basarat ...
Roko C. Buljan

Một cái gì đó tôi thường làm liên quan đến việc chia tách một phần:var parts = full_file.split("."); var ext = parts[parts.length-1]; var file = parts.splice(0,parts.length-1).join(".");
radicand

x.split (".") thậm chí không được coi là một câu trả lời. Tôi biết tôi sử dụng một '.' trong hầu hết tất cả các quy ước đặt tên tệp của tôi, ví dụ: 'Survey.controll.js' hoặc 'my.family.jpg'.
Lee Brindley

@ Lee2808: Do đó cảnh báo chỉ có một dấu chấm. Điều này chỉ đơn giản là để chỉ ra rằng có một số cách tiếp cận, tùy thuộc vào ứng dụng. Tôi chắc chắn sẽ sử dụng một trong những phương pháp khác trong hầu hết các trường hợp.
Jeff B

x = x.substr(0, x.lastIndexOf('.'));- có lẽ bạn có ý nghĩa x = x.substring(0, x.lastIndexOf('.'));?
Dziad Borowy

39

Có lẽ bạn có thể sử dụng giả định rằng dấu chấm cuối cùng sẽ là dấu phân cách mở rộng.

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

Nếu tệp không có phần mở rộng, nó sẽ trả về chuỗi trống. Để khắc phục việc sử dụng chức năng này

function removeExtension(filename){
    var lastDotPosition = filename.lastIndexOf(".");
    if (lastDotPosition === -1) return filename;
    else return filename.substr(0, lastDotPosition);
}

Cảnh báo, điều này không thành công nếu không có phần mở rộng tên tệp. Bạn còn lại với một chuỗi trống.
Brad

18
Phiên bản ngắn hơn mà không có dấu chấm. var f = x.substr(0, x.lastIndexOf('.')) || x;Điều này hoạt động vì một chuỗi rỗng là sai, do đó, nó trả về x.
Jonathan Rowny

22

Tôi thích cái này vì nó là một cuốn sách không quá khó đọc:

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


12

Điều này hoạt động, ngay cả khi dấu phân cách không có trong chuỗi.

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"

Cũng có thể được sử dụng như một lớp lót như thế này:

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

EDIT: Đây là một giải pháp hiệu quả hơn:

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

10

Tôi không biết nếu đó là một tùy chọn hợp lệ nhưng tôi sử dụng điều này:

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.

Đó không chỉ là một hoạt động mà tôi biết, mà ít nhất nó phải luôn hoạt động!

CẬP NHẬT: Nếu bạn muốn một oneliner, đây là:

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


1
Nó không nên là name.join ('') mà là name.join ('.'). Bạn chia theo dấu chấm nhưng tham gia bằng dấu phẩy, vì vậy hello.name.txttrả vềhello, name
Evil


7

Đây là một giải pháp dựa trên regex khác:

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

Điều này chỉ nên cắt ra đoạn cuối cùng.


7

Đơn giản

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

6

Câu trả lời được chấp nhận loại bỏ phần mở rộng cuối cùng chỉ ( .jpeg), có thể là một lựa chọn tốt trong hầu hết các trường hợp.

Tôi đã từng phải loại bỏ tất cả các phần mở rộng ( .tar.gz) và tên tệp bị hạn chế không chứa dấu chấm (vì vậy 2015-01-01.backup.tarsẽ không có vấn đề gì):

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


3

Nếu bạn phải xử lý một biến chứa đường dẫn đầy đủ (ví dụ thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg":) và bạn muốn trả về chỉ "tên tệp", bạn có thể sử dụng:

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

kết quả sẽ là theName == "tên tệp" ;

Để thử, hãy viết lệnh sau vào cửa sổ giao diện điều khiển trình gỡ lỗi chrome của bạn: window.location.pathname.split("/").slice(-1).join().split(".").shift()

Nếu bạn phải xử lý chỉ tên tệp và phần mở rộng của nó (ví dụ theNameWithExt = "filename.jpg":):

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

kết quả sẽ là theName == "tên tệp" , giống như trên;

Ghi chú:

  1. Đầu tiên là một chút chậm hơn nguyên nhân thực hiện nhiều hoạt động hơn; nhưng hoạt động trong cả hai trường hợp, nói cách khác, nó có thể trích xuất tên tệp mà không cần mở rộng từ một chuỗi đã cho có chứa đường dẫn hoặc tên tệp với ex. Trong khi biến thứ hai chỉ hoạt động nếu biến đã cho chứa tên tệp có ext như filename.ext nhưng nhanh hơn một chút.
  2. Cả hai giải pháp đều hoạt động cho cả tệp cục bộ và tệp máy chủ;

Nhưng tôi không thể nói gì về việc so sánh hiệu suất với các câu trả lời khác cũng như khả năng tương thích của trình duyệt hoặc hệ điều hành.

đoạn trích làm việc 1: đường dẫn hoàn chỉnh

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

đoạn trích làm việc 2: tên tệp có phần mở rộng

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

đoạn trích làm việc 2: tên tệp có phần mở rộng gấp đôi

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


3

Mặc dù đã khá muộn nhưng tôi sẽ thêm một cách tiếp cận khác để lấy tên tệp mà không cần mở rộng bằng cách sử dụng JS cũ đơn giản-

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


hoặc path.split('.').pop()cho một phần mở rộng tệp
mixdev

Anh ta thực sự đang cố lấy tên tập tin chứ không phải phần mở rộng!
Munim Dibosh

3

Node.js xóa tiện ích mở rộng khỏi thư mục giữ đường dẫn đầy đủ

https://stackoverflow.com/a/31615711/895245 chẳng hạn đã làm path/hello.html-> hello, nhưng nếu bạn muốn path/hello.html-> path/hello, bạn có thể sử dụng điều này:

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

thư mục đầu ra là tốt:

path/hello

https://stackoverflow.com/a/36099196/895245 cũng đạt được điều này, nhưng tôi thấy cách tiếp cận này có một chút hài lòng về mặt ngữ nghĩa.

Đã thử nghiệm trong Node.js v10.15.2.


0

Đây là nơi biểu thức thông thường có ích! .replace()Phương pháp của Javascript sẽ có một biểu thức chính quy và bạn có thể sử dụng điều đó để thực hiện những gì bạn muốn:

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

0

Một lớp lót khác - chúng tôi giả sử tệp của chúng tôi là ảnh jpg >> ex: var yourStr = 'test.jpg';

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

0

Bạn có thể sử dụng pathđể điều động.

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

Đầu ra

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


0

Đây là mã tôi sử dụng để xóa phần mở rộng khỏi tên tệp mà không sử dụng regex hoặc indexOf (indexOf không được hỗ trợ trong IE8). Nó giả định rằng phần mở rộng là bất kỳ văn bản nào sau '.' Cuối cùng tính cách.

Nó hoạt động cho:

  • các tệp không có phần mở rộng: "myletter"
  • các tệp có '.' trong tên: "my.letter.txt"
  • độ dài phần mở rộng tệp không xác định: "my.letter.html"

Đây là mã:

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

thất bại với hello.tar.gz, đầu ra là hellotar.
Asif Ali

#AsifAli cảm ơn bạn là đúng, tôi quên cài đặt lại phần mở rộng tập tin. Tôi đã cập nhật câu trả lời, tôi hy vọng nó hoạt động ngay bây giờ.
Não nhỏ

-3

Tôi sẽ sử dụng một cái gì đó như x.sub chuỗi (0, x.lastIndexOf ('.')). Nếu bạn đang đi cho hiệu suất, đừng sử dụng javascript :-p Không, một tuyên bố nữa thực sự không quan trọng đối với 99.99999% của tất cả các mục đích.


2
"Nếu bạn đang đi cho hiệu suất, đừng sử dụng javascript" - Bạn còn đề xuất sử dụng gì khác trong các ứng dụng web ..?
TJ

Anh ấy không đề cập đến các ứng dụng web.
Lucas Moeskops

1
Câu hỏi này đã được hỏi và câu trả lời đã được đăng vào năm 2010, 7 năm trước và JavaScript chỉ được sử dụng khá nhiều trong các ứng dụng web. (Nút được sinh ra, nó thậm chí không có hướng dẫn hoặc NPM tại thời điểm đó)
TJ

;-) Tuy nhiên, nếu hiệu suất quan trọng đối với các nhiệm vụ như thế này, bạn có thể xem xét thực hiện việc này trên phụ trợ và xử lý kết quả trên lối vào.
Lucas Moeskops
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.