Làm cách nào tôi có thể mở rộng tệp bằng JavaScript?


501

Xem mã:

var file1 = "50.xsl";
var file2 = "30.doc";
getFileExtension(file1); //returns xsl
getFileExtension(file2); //returns doc

function getFileExtension(filename) {
    /*TODO*/
}

Câu trả lời:


796

Chỉnh sửa mới hơn: Rất nhiều điều đã thay đổi kể từ khi câu hỏi này được đăng lần đầu - có rất nhiều thông tin thực sự tốt trong câu trả lời sửa đổi của wallacer cũng như sự cố tuyệt vời của VisioN


Chỉnh sửa: Chỉ vì đây là câu trả lời được chấp nhận; Câu trả lời của wallacer thực sự tốt hơn nhiều:

return filename.split('.').pop();

Câu trả lời cũ của tôi:

return /[^.]+$/.exec(filename);

Hãy làm nó.

Chỉnh sửa: Để phản hồi bình luận của PhiLho, hãy sử dụng nội dung như:

return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined;

1
Nó không tốn kém để thực hiện regex hai lần?
Andrew Hedges

5
Câu trả lời được đánh giá cao dưới đây là tốt hơn nhiều.
fletom

2
Thật không may, cả hai giải pháp đều thất bại đối với các tên như file.htaccess .
VisioN

3
Tất cả các trường hợp có thể được xử lý như sau: return filename.split ("."). Lát (1) .pop () || "";
JustAndrei

1
@JustAndrei Vẫn chưa phải là tất cả :) Đối với tên tệp thuần (tên cơ sở?), Không phải là một đường dẫn, vì lý do thực tế, tôi nghĩ rằng nó nên return filename.substring(0,1) === '.' ? '' : filename.split('.').slice(1).pop() || '';quan tâm đến .fileloại tệp Unix (tôi bị ẩn, tôi tin). Đó là nếu bạn muốn giữ nó như một lớp lót, một chút lộn xộn theo sở thích của tôi.
kooker

833
return filename.split('.').pop();

Giữ cho nó đơn giản :)

Biên tập:

Đây là một giải pháp phi regex khác mà tôi tin là hiệu quả hơn:

return filename.substring(filename.lastIndexOf('.')+1, filename.length) || filename;

Có một số trường hợp góc được xử lý tốt hơn bằng câu trả lời của VisioN bên dưới, đặc biệt là các tệp không có phần mở rộng ( .htaccessbao gồm vv).

Nó rất hiệu quả và xử lý các trường hợp góc theo cách tốt hơn có thể được cho là bằng cách quay lại ""thay vì chuỗi đầy đủ khi không có dấu chấm hoặc không có chuỗi trước dấu chấm. Đó là một giải pháp được chế tạo rất tốt, mặc dù khó đọc. Dán nó trong lib người trợ giúp của bạn và chỉ cần sử dụng nó.

Chỉnh sửa cũ:

Việc triển khai an toàn hơn nếu bạn chạy vào các tệp không có phần mở rộng hoặc các tệp bị ẩn không có phần mở rộng (xem bình luận của VisioN cho câu trả lời của Tom ở trên) sẽ là một cái gì đó dọc theo những dòng này

var a = filename.split(".");
if( a.length === 1 || ( a[0] === "" && a.length === 2 ) ) {
    return "";
}
return a.pop();    // feel free to tack .toLowerCase() here if you want

Nếu a.lengthlà một, đó là một tệp hiển thị không có phần mở rộng tức là. tập tin

Nếu a[0] === ""a.length === 2đó là một tập tin ẩn không có phần mở rộng tức là. .htaccess

Hy vọng điều này sẽ giúp làm sáng tỏ vấn đề với các trường hợp phức tạp hơn một chút. Về hiệu suất, tôi tin rằng giải pháp này chậm hơn một chút so với regex trong hầu hết các trình duyệt. Tuy nhiên, đối với hầu hết các mục đích phổ biến, mã này phải hoàn toàn có thể sử dụng được.


4
Tôi không thể nhận xét về hiệu suất, nhưng cái này chắc chắn trông sạch sẽ! Tôi đang sử dụng nó. +1
pc1oad1etter

6
nhưng trong trường hợp này tên tệp trông giống như filname.tes.test.jpg. Vui lòng xem xét đầu ra. Tôi hy vọng nó sẽ sai.
Fero

19
trong trường hợp đó, đầu ra là "jpg"
wallacer

1
Xuất sắc! Cảm ơn rất nhiều. Thật tuyệt khi thấy một giải pháp không sử dụng regex; Tôi đã làm điều này với PHP và nó chỉ sử dụng một vài hàm. +1
Bojangles

3
@wallacer: Điều gì xảy ra nếu filenamethực sự không có tiện ích mở rộng? Điều này không chỉ đơn giản là trả lại tên tệp cơ sở, sẽ là xấu?
Nicol Bolas

287

Giải pháp sau đây đủ nhanhngắn để sử dụng trong các hoạt động hàng loạt và lưu thêm byte:

 return fname.slice((fname.lastIndexOf(".") - 1 >>> 0) + 2);

Đây là một giải pháp phổ quát không giới hạn một dòng khác:

 return fname.slice((Math.max(0, fname.lastIndexOf(".")) || Infinity) + 1);

Cả hai đều hoạt động chính xác với các tên không có phần mở rộng (ví dụ: myfile ) hoặc bắt đầu bằng .dấu chấm (ví dụ: .htaccess ):

 ""                            -->   ""
 "name"                        -->   ""
 "name.txt"                    -->   "txt"
 ".htpasswd"                   -->   ""
 "name.with.many.dots.myext"   -->   "myext"

Nếu bạn quan tâm đến tốc độ bạn có thể chạy điểm chuẩn và kiểm tra xem các giải pháp được cung cấp là nhanh nhất, trong khi giải pháp ngắn thì cực kỳ nhanh:

So sánh tốc độ

Làm thế nào ngắn hoạt động:

  1. String.lastIndexOfphương thức trả về vị trí cuối cùng của chuỗi con (tức là ".") trong chuỗi đã cho (tức là fname). Nếu chuỗi con không tìm thấy phương thức trả về -1.
  2. Vị trí "không thể chấp nhận" của dấu chấm trong tên tệp là -10, tương ứng là các tên không có phần mở rộng (ví dụ "name") và các tên bắt đầu bằng dấu chấm (ví dụ ".htaccess").
  3. Toán tử dịch chuyển bên phải bằng không ( >>>) nếu được sử dụng với số 0 ảnh hưởng đến các số âm chuyển -1sang 4294967295-2thành 4294967294, điều này rất hữu ích cho việc giữ nguyên tên tệp trong các trường hợp cạnh (sắp xếp một mẹo ở đây).
  4. String.prototype.slicetrích xuất một phần tên tệp từ vị trí được tính như mô tả. Nếu số vị trí lớn hơn độ dài của phương thức chuỗi trả về "".

Nếu bạn muốn giải pháp rõ ràng hơn sẽ hoạt động theo cùng một cách (cộng với sự hỗ trợ thêm của đường dẫn đầy đủ), hãy kiểm tra phiên bản mở rộng sau đây. Giải pháp này sẽ chậm hơn so với các lớp lót trước nhưng dễ hiểu hơn nhiều.

function getExtension(path) {
    var basename = path.split(/[\\/]/).pop(),  // extract file name from full path ...
                                               // (supports `\\` and `/` separators)
        pos = basename.lastIndexOf(".");       // get last position of `.`

    if (basename === "" || pos < 1)            // if file name is empty or ...
        return "";                             //  `.` not found (-1) or comes first (0)

    return basename.slice(pos + 1);            // extract extension ignoring `.`
}

console.log( getExtension("/path/to/file.ext") );
// >> "ext"

Tất cả ba biến thể sẽ hoạt động trong bất kỳ trình duyệt web nào ở phía máy khách và cũng có thể được sử dụng trong mã NodeJS phía máy chủ.


5
Không hoạt động. "/home/user/.app/config" trả về "app / config", điều này hoàn toàn sai.
mrbrdo

33
@mrbrdo Phương pháp này không được phép hoạt động với đường dẫn đầy đủ chỉ với tên tệp, theo yêu cầu của câu hỏi. Đọc kỹ câu hỏi trước khi tải xuống.
VisioN

8
Tại sao đi đến độ dài để tối ưu hóa một dòng mã tầm thường như vậy? Các toán tử Tilde và bitshift hiếm khi được nhìn thấy trong JavaScript đến nỗi tôi không thể hỗ trợ câu trả lời như vậy. Nếu phải mất 5 dấu đầu dòng để giải thích cách 1 dòng mã hoạt động, tốt hơn là viết lại mã để nó thực sự dễ hiểu.
Jackson

6
Tốc độ của một dòng này sẽ không tạo ra sự khác biệt rõ ràng trong bất kỳ ứng dụng nào. Bitwise hiếm khi được sử dụng đến mức những người dùng phổ biến như JSLint và JSHint cảnh báo không sử dụng chúng. Nỗi ám ảnh về hiệu suất và tính gọn nhẹ của logic này đã làm giảm chất lượng của mã; nếu mã yêu cầu "điều tra thêm", tôi coi đó là "xấu".
Jackson

10
@Jackson Xem xét đây là một trang web cung cấp nhiều giải pháp cho một vấn đề, có một giải pháp tối ưu hóa hiệu suất không bao giờ là điều xấu. Tuyên bố của bạn "sẽ không tạo ra sự khác biệt rõ ràng trong bất kỳ ứng dụng nào" hoàn toàn dựa trên phạm vi hẹp các ứng dụng có thể sử dụng của bạn. Ngoài ra, nó có thể cung cấp cho ai đó xem xét vấn đề về trải nghiệm học tập mà họ có thể tối ưu hóa một số vấn đề mã khác họ cần để tạo cho một ứng dụng chuyên sâu về máy tính mà họ đang viết.
nrylee

33
function getFileExtension(filename)
{
  var ext = /^.+\.([^.]+)$/.exec(filename);
  return ext == null ? "" : ext[1];
}

Đã thử nghiệm với

"a.b"     (=> "b") 
"a"       (=> "") 
".hidden" (=> "") 
""        (=> "") 
null      (=> "")  

Cũng thế

"a.b.c.d" (=> "d")
".a.b"    (=> "b")
"a..b"    (=> "b")

Để làm cho nó hoạt động trong IE: var mẫu = "^. + \\. ([^.] +) $"; var ext = new RegExp (mẫu);
spc16670

20
function getExt(filename)
{
    var ext = filename.split('.').pop();
    if(ext == filename) return "";
    return ext;
}

8
return (ext === tên tệp)? '': máy lẻ;
Michiel

13
var extension = fileName.substring(fileName.lastIndexOf('.')+1);


8
function file_get_ext(filename)
    {
    return typeof filename != "undefined" ? filename.substring(filename.lastIndexOf(".")+1, filename.length).toLowerCase() : false;
    }

8

/**
 * Extract file extension from URL.
 * @param {String} url
 * @returns {String} File extension or empty string if no extension is present.
 */
var getFileExtension = function (url) {
    "use strict";
    if (url === null) {
        return "";
    }
    var index = url.lastIndexOf("/");
    if (index !== -1) {
        url = url.substring(index + 1); // Keep path without its segments
    }
    index = url.indexOf("?");
    if (index !== -1) {
        url = url.substring(0, index); // Remove query
    }
    index = url.indexOf("#");
    if (index !== -1) {
        url = url.substring(0, index); // Remove fragment
    }
    index = url.lastIndexOf(".");
    return index !== -1
        ? url.substring(index + 1) // Only keep file extension
        : ""; // No extension found
};

Kiểm tra

Lưu ý rằng trong trường hợp không có truy vấn, đoạn vẫn có thể xuất hiện.

"https://www.example.com:8080/segment1/segment2/page.html?foo=bar#fragment" --> "html"
"https://www.example.com:8080/segment1/segment2/page.html#fragment"         --> "html"
"https://www.example.com:8080/segment1/segment2/.htaccess?foo=bar#fragment" --> "htaccess"
"https://www.example.com:8080/segment1/segment2/page?foo=bar#fragment"      --> ""
"https://www.example.com:8080/segment1/segment2/?foo=bar#fragment"          --> ""
""                                                                          --> ""
null                                                                        --> ""
"a.b.c.d"                                                                   --> "d"
".a.b"                                                                      --> "b"
".a.b."                                                                     --> ""
"a...b"                                                                     --> "b"
"..."                                                                       --> ""

Mã thông báo

0 Cảnh báo.


7

Nhanh chóng và hoạt động chính xác với các đường dẫn

(filename.match(/[^\\\/]\.([^.\\\/]+)$/) || [null]).pop()

Một số trường hợp cạnh

/path/.htaccess => null
/dir.with.dot/file => null

Các giải pháp sử dụng phân tách là chậm và các giải pháp với lastIndexOf không xử lý các trường hợp cạnh.


Những trường hợp cạnh có nghĩa là gì? Vui lòng tham khảo giải pháp của tôi ở đây: stackoverflow.com/a/12900504/1249581 . Nó hoạt động tốt trong mọi trường hợp và nhanh hơn nhiều so với bất kỳ regex nào.
VisioN

Tôi đã liệt kê các trường hợp cạnh. Và giải pháp của bạn KHÔNG xử lý chúng đúng cách. Giống như tôi đã viết, hãy thử "/dir.with.dot/file". Mã của bạn trả về "dấu chấm / tệp" sai một cách lố bịch.
mrbrdo

1
Không ai yêu cầu phân tích đường dẫn. Câu hỏi là về việc trích xuất các phần mở rộng từ tên tệp.
VisioN

3
Giống như tôi đã nói với bạn, điều đó chưa bao giờ được nói rõ ràng, và một giải pháp xử lý các đường dẫn rõ ràng hữu ích hơn nhiều. Câu trả lời cho một câu hỏi về SO được cho là hữu ích cho những người khác ngoài người hỏi câu hỏi. Tôi thực sự không nghĩ rằng một giải pháp xử lý một siêu đầu vào nên được hạ cấp.
mrbrdo

3
Các downvote là để sử dụng biến toàn cầu với .exec(). Mã của bạn sẽ tốt hơn như (filename.match(/[^\\/]\.([^\\/.]+)$/) || [null]).pop().
VisioN

6

tôi chỉ muốn chia sẻ điều này.

fileName.slice(fileName.lastIndexOf('.'))

mặc dù điều này có một nhược điểm là các tệp không có phần mở rộng sẽ trả về chuỗi cuối cùng. nhưng nếu bạn làm như vậy thì điều này sẽ khắc phục mọi thứ:

   function getExtention(fileName){
     var i = fileName.lastIndexOf('.');
     if(i === -1 ) return false;
     return fileName.slice(i)
   }

Theo như tôi nhớ thì slicephương thức này đề cập đến các mảng hơn là các chuỗi. Đối với chuỗi substrhoặc substringsẽ làm việc.
VisioN

@VisioN nhưng tôi đoán bạn nên biết rằng có String.prototype.slicevà cũng Array.prototype.slicevậy nên cả hai cách làm việc đều là phương pháp
Hussein Nazzal

1
À, vâng. Bạn đúng rồi. Hoàn toàn quên mất phương pháp này. Lỗi của tôi.
VisioN

5

Tôi chắc chắn ai đó có thể, và sẽ, giảm thiểu và / hoặc tối ưu hóa mã của tôi trong tương lai. Nhưng, tính đến thời điểm hiện tại , tôi tin tưởng 200% rằng mã của tôi hoạt động trong mọi tình huống duy nhất (ví dụ: chỉ với tên tệp , với URL tương đối , gốc tương đối và URL tuyệt đối , với thẻ phân đoạn # , với chuỗi truy vấn ? và bất cứ điều gì nếu không bạn có thể quyết định ném vào nó), hoàn hảo, và với độ chính xác điểm chính xác.

Để chứng minh, hãy truy cập: https://projects.jamesandersonjr.com/web/js_projects/get_file_extension_test.php

Đây là JSFiddle: https://jsfiddle.net/JamesAndersonJr/ffcdd5z3/

Không được quá tự tin, hoặc thổi kèn của riêng tôi, nhưng tôi chưa thấy bất kỳ khối mã nào cho tác vụ này (tìm phần mở rộng tệp 'chính xác' , giữa một loạt các functionđối số đầu vào khác nhau ) hoạt động tốt như vậy.

Lưu ý: Theo thiết kế, nếu phần mở rộng tệp không tồn tại cho chuỗi đầu vào đã cho, nó chỉ trả về một chuỗi trống "", không phải là lỗi, cũng không phải là thông báo lỗi.

Phải mất hai đối số:

  • Chuỗi: fileNameOrURL (tự giải thích)

  • Boolean: showUnixDotFiles (Có hay không hiển thị các tệp bắt đầu bằng dấu chấm ".")

Lưu ý (2): Nếu bạn thích mã của tôi, hãy chắc chắn thêm nó vào thư viện js của bạn và / hoặc repo, bởi vì tôi đã làm việc chăm chỉ để hoàn thiện nó, và sẽ rất xấu hổ khi lãng phí. Vì vậy, không có thêm rắc rối, đây là:

function getFileExtension(fileNameOrURL, showUnixDotFiles)
    {
        /* First, let's declare some preliminary variables we'll need later on. */
        var fileName;
        var fileExt;

        /* Now we'll create a hidden anchor ('a') element (Note: No need to append this element to the document). */
        var hiddenLink = document.createElement('a');

        /* Just for fun, we'll add a CSS attribute of [ style.display = "none" ]. Remember: You can never be too sure! */
        hiddenLink.style.display = "none";

        /* Set the 'href' attribute of the hidden link we just created, to the 'fileNameOrURL' argument received by this function. */
        hiddenLink.setAttribute('href', fileNameOrURL);

        /* Now, let's take advantage of the browser's built-in parser, to remove elements from the original 'fileNameOrURL' argument received by this function, without actually modifying our newly created hidden 'anchor' element.*/ 
        fileNameOrURL = fileNameOrURL.replace(hiddenLink.protocol, ""); /* First, let's strip out the protocol, if there is one. */
        fileNameOrURL = fileNameOrURL.replace(hiddenLink.hostname, ""); /* Now, we'll strip out the host-name (i.e. domain-name) if there is one. */
        fileNameOrURL = fileNameOrURL.replace(":" + hiddenLink.port, ""); /* Now finally, we'll strip out the port number, if there is one (Kinda overkill though ;-)). */  

        /* Now, we're ready to finish processing the 'fileNameOrURL' variable by removing unnecessary parts, to isolate the file name. */

        /* Operations for working with [relative, root-relative, and absolute] URL's ONLY [BEGIN] */ 

        /* Break the possible URL at the [ '?' ] and take first part, to shave of the entire query string ( everything after the '?'), if it exist. */
        fileNameOrURL = fileNameOrURL.split('?')[0];

        /* Sometimes URL's don't have query's, but DO have a fragment [ # ](i.e 'reference anchor'), so we should also do the same for the fragment tag [ # ]. */
        fileNameOrURL = fileNameOrURL.split('#')[0];

        /* Now that we have just the URL 'ALONE', Let's remove everything to the last slash in URL, to isolate the file name. */
        fileNameOrURL = fileNameOrURL.substr(1 + fileNameOrURL.lastIndexOf("/"));

        /* Operations for working with [relative, root-relative, and absolute] URL's ONLY [END] */ 

        /* Now, 'fileNameOrURL' should just be 'fileName' */
        fileName = fileNameOrURL;

        /* Now, we check if we should show UNIX dot-files, or not. This should be either 'true' or 'false'. */  
        if ( showUnixDotFiles == false )
            {
                /* If not ('false'), we should check if the filename starts with a period (indicating it's a UNIX dot-file). */
                if ( fileName.startsWith(".") )
                    {
                        /* If so, we return a blank string to the function caller. Our job here, is done! */
                        return "";
                    };
            };

        /* Now, let's get everything after the period in the filename (i.e. the correct 'file extension'). */
        fileExt = fileName.substr(1 + fileName.lastIndexOf("."));

        /* Now that we've discovered the correct file extension, let's return it to the function caller. */
        return fileExt;
    };

Thưởng thức! Bạn khá chào mừng!:


1
Tuyệt vời. Cảm ơn!
GollyJer

5

// 获取文件后缀名
function getFileExtension(file) {
  var regexp = /\.([0-9a-z]+)(?:[\?#]|$)/i;
  var extension = file.match(regexp);
  return extension && extension[1];
}

console.log(getFileExtension("https://www.example.com:8080/path/name/foo"));
console.log(getFileExtension("https://www.example.com:8080/path/name/foo.BAR"));
console.log(getFileExtension("https://www.example.com:8080/path/name/.quz/foo.bar?key=value#fragment"));
console.log(getFileExtension("https://www.example.com:8080/path/name/.quz.bar?key=value#fragment"));


5

Nếu bạn đang xử lý các url web, bạn có thể sử dụng:

function getExt(filepath){
     return filepath.split("?")[0].split("#")[0].split('.').pop();
}

getExt("../js/logic.v2.min.js") // js
getExt("http://example.net/site/page.php?id=16548") // php
getExt("http://example.net/site/page.html#welcome.to.me") // html
getExt("c:\\logs\\yesterday.log"); // log

Bản trình diễn: https://jsfiddle.net/squadjot/q5ard4fj/


Tôi thực sự thích giải pháp của bạn. Nó làm rất nhiều với rất ít. Tôi sẽ sử dụng nó.
Jules Manson

4

Thử cái này:

function getFileExtension(filename) {
  var fileinput = document.getElementById(filename);
  if (!fileinput)
    return "";
  var filename = fileinput.value;
  if (filename.length == 0)
    return "";
  var dot = filename.lastIndexOf(".");
  if (dot == -1)
    return "";
  var extension = filename.substr(dot, filename.length);
  return extension;
}

3
return filename.replace(/\.([a-zA-Z0-9]+)$/, "$1");

chỉnh sửa: Thật kỳ lạ (hoặc có thể không phải) $1trong đối số thứ hai của phương thức thay thế dường như không hoạt động ... Xin lỗi.


1
Nó hoạt động hoàn hảo, nhưng bạn đã bỏ lỡ rằng bạn sẽ phải xóa tất cả nội dung khác của chuỗi: return filename.replace (/ ^. *? \. ([A-zA-Z0-9] +) $ /, "$ 1");
roenving

3

Tôi chỉ nhận ra rằng không đủ để đưa ra nhận xét về câu trả lời của p4bl0, mặc dù câu trả lời của Tom giải quyết rõ ràng vấn đề:

return filename.replace(/^.*?\.([a-zA-Z0-9]+)$/, "$1");

3

Đối với hầu hết các ứng dụng, một tập lệnh đơn giản như

return /[^.]+$/.exec(filename);

sẽ hoạt động tốt (như được cung cấp bởi Tom). Tuy nhiên đây không phải là bằng chứng ngu ngốc. Nó không hoạt động nếu tên tệp sau được cung cấp:

image.jpg?foo=bar

Nó có thể là một chút quá mức nhưng tôi sẽ đề nghị sử dụng một trình phân tích cú pháp url như cái này để tránh thất bại do tên tệp không thể đoán trước.

Sử dụng chức năng cụ thể đó, bạn có thể nhận được tên tệp như thế này:

var trueFileName = parse_url('image.jpg?foo=bar').file;

Điều này sẽ xuất ra "image.jpg" mà không có các url url. Sau đó, bạn được tự do lấy phần mở rộng tập tin.


3
function func() {
  var val = document.frm.filename.value;
  var arr = val.split(".");
  alert(arr[arr.length - 1]);
  var arr1 = val.split("\\");
  alert(arr1[arr1.length - 2]);
  if (arr[1] == "gif" || arr[1] == "bmp" || arr[1] == "jpeg") {
    alert("this is an image file ");
  } else {
    alert("this is not an image file");
  }
}

3
function extension(fname) {
  var pos = fname.lastIndexOf(".");
  var strlen = fname.length;
  if (pos != -1 && strlen != pos + 1) {
    var ext = fname.split(".");
    var len = ext.length;
    var extension = ext[len - 1].toLowerCase();
  } else {
    extension = "No extension found";
  }
  return extension;
}

//sử dụng

tiện ích mở rộng ('file.jpeg')

luôn trả về phần mở rộng thấp hơn để bạn có thể kiểm tra phần mở rộng trên trường hoạt động cho:

tập tin.JpEg

tập tin (không có phần mở rộng)

tập tin. (Không gia hạn)


3

Nếu bạn đang tìm kiếm một phần mở rộng cụ thể và biết chiều dài của nó, bạn có thể sử dụng substr :

var file1 = "50.xsl";

if (file1.substr(-4) == '.xsl') {
  // do something
}

Tham khảo JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr


1
Vẻ đẹp đi kèm với sự đơn giản. Đây là câu trả lời thông minh nhất, thanh lịch hơn và hiệu quả hơn trong tất cả. Tôi luôn sử dụng String.substr (-3) hoặc String.substr (-4) để lấy các tiện ích mở rộng trên các hệ thống dựa trên Windows. Tại sao ai đó muốn sử dụng các biểu thức thông thường và các vòng lặp điên cho điều đó.
asiby

13
@asiby Loại giải pháp này là lý do chính khiến tên lửa không gian bị rơi sau khi phóng.
VisioN

3

Tôi đến nhiều bữa tiệc muộn nhưng để đơn giản, tôi sử dụng một cái gì đó như thế này

var fileName = "I.Am.FileName.docx";
var nameLen = fileName.length;
var lastDotPos = fileName.lastIndexOf(".");
var fileNameSub = false;
if(lastDotPos === -1)
{
    fileNameSub = false;
}
else
{
    //Remove +1 if you want the "." left too
    fileNameSub = fileName.substr(lastDotPos + 1, nameLen);
}
document.getElementById("showInMe").innerHTML = fileNameSub;
<div id="showInMe"></div>


3

Có một chức năng thư viện tiêu chuẩn cho điều này trong pathmô-đun:

import path from 'path';

console.log(path.extname('abc.txt'));

Đầu ra:

.txt

Vì vậy, nếu bạn chỉ muốn định dạng:

path.extname('abc.txt').slice(1) // 'txt'

Nếu không có phần mở rộng, thì hàm sẽ trả về một chuỗi rỗng:

path.extname('abc') // ''

Nếu bạn đang sử dụng Node, thì pathđược tích hợp sẵn. Nếu bạn đang nhắm mục tiêu trình duyệt, thì Webpack sẽ gói một pathtriển khai cho bạn. Nếu bạn đang nhắm mục tiêu trình duyệt mà không có Webpack, thì bạn có thể bao gồm đường dẫn trình duyệt theo cách thủ công.

Không có lý do để thực hiện tách chuỗi hoặc regex.


Ai nói gì về nút?
Shannon Hochkins

Đối số của bạn về việc không sử dụng phân tách hoặc biểu thức chính quy là bao gồm plugin hoặc gói ứng dụng với nút, đó là câu trả lời vượt trội cho nhiệm vụ cấp độ
Shannon Hochkins

@ShannonHochkins hầu hết thời gian bạn có những thứ này được thiết lập bằng mọi cách
sdgfsdh

@AndreiDraganescu Tôi không có ý định hạ thấp nó, vì vậy đã giảm bớt.
sdgfsdh

3

"one-liner" để lấy tên tệp và phần mở rộng bằng cách sử dụng reducehủy mảng :

var str = "filename.with_dot.png";
var [filename, extension] = str.split('.').reduce((acc, val, i, arr) => (i == arr.length - 1) ? [acc[0].substring(1), val] : [[acc[0], val].join('.')], [])

console.log({filename, extension});

với vết lõm tốt hơn:

var str = "filename.with_dot.png";
var [filename, extension] = str.split('.')
   .reduce((acc, val, i, arr) => (i == arr.length - 1) 
       ? [acc[0].substring(1), val] 
       : [[acc[0], val].join('.')], [])


console.log({filename, extension});

// {
//   "filename": "filename.with_dot",
//   "extension": "png"
// }

Điều này không hoạt động trong IE 11
Gokul Maha

Bạn có thể sử dụng babel / typecript / polyfills cho các tính năng ES7 + bị thiếu của IE 11
boehm_s

2

Một giải pháp một dòng cũng sẽ chiếm các tham số truy vấn và bất kỳ ký tự nào trong url.

string.match(/(.*)\??/i).shift().replace(/\?.*/, '').split('.').pop()

// Example
// some.url.com/with.in/&ot.s/files/file.jpg?spec=1&.ext=jpg
// jpg

(1) Nếu một tệp không có phần mở rộng, điều này vẫn sẽ trả về tên tệp. (2) Nếu có một đoạn trong URL, nhưng không có truy vấn (ví dụ page.html#fragment), điều này sẽ trả về phần mở rộng tệp và đoạn.
Jack

2

Giải pháp đơn giản này

function extension(filename) {
  var r = /.+\.(.+)$/.exec(filename);
  return r ? r[1] : null;
}

Xét nghiệm

/* tests */
test('cat.gif', 'gif');
test('main.c', 'c');
test('file.with.multiple.dots.zip', 'zip');
test('.htaccess', null);
test('noextension.', null);
test('noextension', null);
test('', null);

// test utility function
function test(input, expect) {
  var result = extension(input);
  if (result === expect)
    console.log(result, input);
  else
    console.error(result, input);
}

function extension(filename) {
  var r = /.+\.(.+)$/.exec(filename);
  return r ? r[1] : null;
}


1

Câu trả lời của Wallacer là tốt, nhưng cần thêm một lần kiểm tra.

Nếu tệp không có phần mở rộng, nó sẽ sử dụng tên tệp làm phần mở rộng không tốt.

Hãy thử cái này:

return ( filename.indexOf('.') > 0 ) ? filename.split('.').pop().toLowerCase() : 'undefined';

1

Đừng quên rằng một số tệp có thể không có phần mở rộng, vì vậy:

var parts = filename.split('.');
return (parts.length > 1) ? parts.pop() : '';

1
var file = "hello.txt";
var ext = (function(file, lio) { 
  return lio === -1 ? undefined : file.substring(lio+1); 
})(file, file.lastIndexOf("."));

// hello.txt -> txt
// hello.dolly.txt -> txt
// hello -> undefined
// .hello -> hello

1
fetchFileExtention(fileName) {
    return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2);
}

2
Mặc dù đoạn mã này có thể giải quyết câu hỏi, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn.
Brett DeWoody
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.