ฉันจะรับไฟล์นามสกุลด้วย JavaScript ได้อย่างไร?


คำตอบ:


796

ใหม่กว่าแก้ไข:สิ่งต่าง ๆ มีการเปลี่ยนแปลงนับตั้งแต่คำถามนี้ถูกโพสต์ครั้งแรก - มีข้อมูลจำนวนมากที่ดีในคำตอบที่แก้ไขแล้วของวอลเลอร์รวมถึงการวิเคราะห์ที่ยอดเยี่ยมของVisioN


แก้ไข:เพียงเพราะนี่เป็นคำตอบที่ยอมรับได้ คำตอบของ wallererนั้นดีกว่ามาก:

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

คำตอบเก่าของฉัน:

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

ควรทำอย่างไร

แก้ไข:เพื่อตอบสนองต่อความคิดเห็นของ PhiLho ให้ใช้สิ่งที่ชอบ:

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

1
การดำเนินการ regex สองครั้งมีราคาแพงหรือไม่
Andrew Hedges

5
คำตอบที่ได้รับคะแนนสูงด้านล่างนั้นดีกว่ามาก
fletom

2
น่าเสียดายที่โซลูชันทั้งสองล้มเหลวสำหรับชื่อเช่นไฟล์และ. htaccess
VisioN

3
กรณีที่เป็นไปได้ทั้งหมดจะถูกประมวลผลดังนี้: return filename.split ("."). slice (1) .pop () || "";
JustAndrei

1
@ JustAndrei ยังคงไม่ทั้งหมด :) สำหรับชื่อไฟล์บริสุทธิ์ (ชื่อฐาน?) ไม่ใช่เส้นทางสำหรับเหตุผลในทางปฏิบัติฉันคิดว่ามันควรจะเป็นreturn filename.substring(0,1) === '.' ? '' : filename.split('.').slice(1).pop() || '';สิ่งนี้จะดูแล.file(Unix ซ่อนฉันเชื่อว่า) ชนิดของไฟล์เช่นกัน นั่นคือถ้าคุณต้องการที่จะให้มันเป็นหนึ่งซับซึ่งเป็นบิตที่ยุ่งกับรสนิยมของฉัน
kooker

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

ง่าย ๆ เข้าไว้ :)

แก้ไข:

นี่เป็นอีกวิธีที่ไม่ใช่ regex ที่ฉันเชื่อว่ามีประสิทธิภาพมากขึ้น:

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

มีบางกรณีมุมที่จัดการได้ดีขึ้นโดยคำตอบของ VisioNด้านล่างโดยเฉพาะไฟล์ที่ไม่มีนามสกุล (.htaccessรวมอยู่ด้วย)

มันมีประสิทธิภาพมากและจัดการกับมุมของเคสในวิธีที่ดีกว่าโดยกลับมา""แทนที่สตริงเต็มเมื่อไม่มีจุดหรือไม่มีสตริงก่อนหน้าจุด มันเป็นวิธีที่ออกแบบมาอย่างดีแม้ว่าจะอ่านยาก ติดไว้ใน lib ผู้ช่วยของคุณและเพียงแค่ใช้มัน

แก้ไขเก่า:

การใช้งานที่ปลอดภัยยิ่งขึ้นหากคุณกำลังเรียกใช้ไฟล์ที่ไม่มีส่วนขยายหรือไฟล์ที่ซ่อนอยู่ซึ่งไม่มีส่วนขยาย (ดูความคิดเห็นของ VisioN ต่อคำตอบของ Tom ด้านบน) จะเป็นบางสิ่งตามสายเหล่านี้

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

ถ้าa.lengthเป็นไฟล์นี้จะเป็นไฟล์ที่มองเห็นโดยไม่มีนามสกุล ไฟล์

ถ้าa[0] === ""และa.length === 2มันเป็นไฟล์ที่ซ่อนอยู่ซึ่งไม่มีนามสกุล .htaccess

หวังว่าสิ่งนี้จะช่วยในการแก้ไขปัญหาที่มีความซับซ้อนมากขึ้นเล็กน้อย ในแง่ของประสิทธิภาพฉันเชื่อว่าวิธีนี้ช้ากว่า regex เล็กน้อยในเบราว์เซอร์ส่วนใหญ่ อย่างไรก็ตามสำหรับจุดประสงค์ทั่วไปรหัสนี้ควรใช้งานได้อย่างสมบูรณ์แบบ


4
ฉันไม่สามารถออกความเห็นเกี่ยวกับการแสดงได้ แต่อันนี้ดูสะอาดแล้ว! ฉันใช้มัน +1
pc1oad1etter

6
แต่ในกรณีนี้ชื่อไฟล์ดูเหมือน filname.tes.test.jpg โปรดพิจารณาผลลัพธ์ ฉันหวังว่ามันจะเป็นเท็จ
Fero

19
ในกรณีนั้นผลลัพธ์คือ "jpg"
wallacer

1
ยอดเยี่ยม! ขอบคุณมาก ๆ. ยินดีที่ได้เห็นวิธีแก้ปัญหาที่ไม่ได้ใช้ regex ฉันทำสิ่งนี้ด้วย PHP และใช้เพียงสองฟังก์ชันเท่านั้น +1
Bojangles

3
@wallacer: จะเกิดอะไรขึ้นหากfilenameจริง ๆ แล้วไม่มีส่วนขยาย นี่จะไม่ใช่แค่คืนชื่อไฟล์พื้นฐานซึ่งจะไม่ดีใช่ไหม
Nicol Bolas

287

วิธีแก้ปัญหาต่อไปนี้รวดเร็วและสั้นพอที่จะใช้ในการดำเนินการจำนวนมากและบันทึกไบต์พิเศษ:

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

นี่เป็นอีกวิธีการแก้ปัญหาสากลที่ไม่ใช่ regexp แบบบรรทัดเดียว:

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

ทั้งสองทำงานอย่างถูกต้องกับชื่อที่ไม่มีนามสกุล (เช่นmyfile ) หรือเริ่มต้นด้วย.จุด (เช่น. htaccess ):

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

หากคุณสนใจความเร็วคุณสามารถรันเกณฑ์มาตรฐานและตรวจสอบว่าโซลูชันที่ให้มานั้นเร็วที่สุดในขณะที่สั้นนั้นเร็วมาก:

เปรียบเทียบความเร็ว

วิธีการที่สั้นทำงาน:

  1. String.lastIndexOfวิธีการส่งกลับตำแหน่งสุดท้ายของสตริงย่อย (เช่น".") ในสตริงที่กำหนด (เช่นfname) หากสตริงย่อยไม่พบวิธีการส่งกลับ-1ถ้าย่อยไม่พบวิธีการส่งกลับ
  2. ตำแหน่ง "จุดที่ยอมรับไม่ได้" ของจุดในชื่อไฟล์คือ-1และ0ซึ่งตามลำดับอ้างถึงชื่อที่ไม่มีส่วนขยาย (เช่น"name") และชื่อที่ขึ้นต้นด้วยจุด (เช่น".htaccess")
  3. ศูนย์เติมประกอบการเปลี่ยนแปลงทางขวา ( >>>) ถ้าใช้กับศูนย์ส่งผลกระทบต่อตัวเลขติดลบเปลี่ยน-1ไป4294967295และ-2ไป4294967294ซึ่งจะเป็นประโยชน์สำหรับเหลือชื่อไฟล์ไม่เปลี่ยนแปลงในกรณีขอบ (เรียงลำดับของเคล็ดลับที่นี่)
  4. String.prototype.sliceแยกส่วนของชื่อไฟล์จากตำแหน่งที่คำนวณตามที่อธิบายไว้ ""ถ้าจำนวนตำแหน่งที่เป็นมากกว่าความยาวของวิธีการส่งกลับสตริง

หากคุณต้องการโซลูชันที่ชัดเจนยิ่งขึ้นซึ่งจะทำงานในลักษณะเดียวกัน (พร้อมกับการสนับสนุนเพิ่มเติมของพา ธ แบบเต็ม) ให้ตรวจสอบเวอร์ชันเพิ่มเติมต่อไปนี้ การแก้ปัญหานี้จะช้ากว่าหนึ่งตอร์ปิโดก่อนหน้านี้ แต่ง่ายต่อการเข้าใจ

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"

ตัวแปรทั้งสามควรทำงานในเว็บเบราว์เซอร์ใดก็ได้ในฝั่งไคลเอ็นต์และสามารถใช้ในโค้ด NodeJS ฝั่งเซิร์ฟเวอร์ได้เช่นกัน


5
ไม่ทำงาน, ไม่เป็นผล. "/home/user/.app/config" ส่งคืน "app / config" ซึ่งผิดทั้งหมด
mrbrdo

33
@mrbrdo วิธีนี้ไม่ควรทำงานกับเส้นทางแบบเต็มเท่านั้นกับชื่อไฟล์ตามที่ร้องขอโดยคำถาม อ่านคำถามอย่างรอบคอบก่อนลงคะแนน
VisioN

8
เหตุใดจึงต้องใช้ความยาวเพื่อเพิ่มประสิทธิภาพของรหัสบรรทัดเล็ก ๆ น้อย ๆ ตัวดำเนินการ Tilde และ bitshift แทบจะไม่เคยเห็นใน JavaScript เลยฉันไม่สามารถหาคำตอบได้ หากใช้สัญลักษณ์แสดงหัวข้อย่อย 5 จุดเพื่ออธิบายวิธีการทำงานของรหัส 1 บรรทัดควรเขียนรหัสใหม่เพื่อให้เข้าใจได้จริง
Jackson

6
ความเร็วของหนึ่งบรรทัดนี้จะไม่สร้างความแตกต่างที่สังเกตได้ในแอปพลิเคชันใด ๆ Bitwise ไม่ค่อยนิยมใช้งาน linters ที่นิยมเช่น JSLint และ JSHint เตือนการใช้งาน การหมกมุ่นกับประสิทธิภาพและความกะทัดรัดของตรรกะนี้ทำให้คุณภาพของโค้ดลดลง หากรหัสต้องการ "การตรวจสอบเพิ่มเติม" ฉันถือว่ามัน "ไม่ดี"
Jackson

10
@Jackson พิจารณาว่านี่เป็นเว็บไซต์สำหรับเสนอวิธีแก้ปัญหาที่หลากหลายให้กับคุณการมีโซลูชันที่ปรับประสิทธิภาพให้เหมาะสมไม่ใช่เรื่องเลวร้าย คุณกำลังแถลงว่า "จะไม่ทำให้เห็นความแตกต่างในแอปพลิเคชันใด ๆ " โดยสมบูรณ์ตามขอบเขตแคบ ๆ ของแอพพลิเคชั่นที่เป็นไปได้ซึ่งสามารถนำมาใช้ได้นอกเหนือจากนั้นอาจทำให้บางคนมองปัญหาประสบการณ์การเรียนรู้ รหัสอื่น ๆ ที่พวกเขาต้องการสำหรับการประมวลผลแอปพลิเคชันแบบเข้มข้นที่พวกเขากำลังเขียน
nrylee

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

ทดสอบกับ

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

ด้วย

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

เพื่อให้ทำงานใน IE: var pattern = "^. + \\. ([^.] +) $"; var ext = RegExp ใหม่ (รูปแบบ);
spc16670

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

8
ส่งคืน (ext === ชื่อไฟล์) หรือไม่ '': ต่อ;
Michiel



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

ทดสอบ

ขอให้สังเกตว่าในกรณีที่ไม่มีการสอบถามชิ้นส่วนอาจยังคงมีอยู่

"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"
"..."                                                                       --> ""

JSLint

0 คำเตือน


7

รวดเร็วและทำงานอย่างถูกต้องกับเส้นทาง

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

บางกรณีขอบ

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

โซลูชันที่ใช้การแบ่งข้อมูลจะช้าและโซลูชันที่มี lastIndexOf จะไม่จัดการกับเคสที่มีขอบ


ขอบกรณีใดที่คุณหมายถึง โปรดดูที่วิธีการแก้ปัญหาของฉันที่นี่: stackoverflow.com/a/12900504/1249581 มันทำงานได้ดีในทุกกรณีและเร็วกว่า regex ใด ๆ
VisioN

ฉันได้ระบุกรณีขอบแล้ว และโซลูชันของคุณไม่สามารถจัดการได้อย่างถูกต้อง เช่นเดียวกับที่ฉันเขียนไปแล้วลอง "/dir.with.dot/file" รหัสของคุณส่งคืน "dot / file" ซึ่งผิดพลาดอย่างน่าขัน
mrbrdo

1
ไม่มีใครขอให้แยกวิเคราะห์เส้นทาง คำถามคือเกี่ยวกับการแยกส่วนขยายจากชื่อไฟล์
VisioN

3
อย่างที่ฉันบอกไปแล้วว่าไม่เคยพูดอย่างชัดเจนและวิธีแก้ปัญหาที่จัดการเส้นทางนั้นมีประโยชน์มากกว่า คำตอบของคำถามเกี่ยวกับ SO นั้นน่าจะมีประโยชน์กับคนอื่นนอกเหนือจากคนที่ถามคำถามนั้น ฉันไม่คิดว่าวิธีแก้ปัญหาที่จัดการกับอินพุทจำนวนมากควรถูกลดระดับลง
mrbrdo

3
downvote .exec()สำหรับใช้ตัวแปรระดับโลกที่มี (filename.match(/[^\\/]\.([^\\/.]+)$/) || [null]).pop()รหัสของคุณจะดีขึ้นเป็น
VisioN

6

ฉันแค่อยากจะแบ่งปันสิ่งนี้

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

แม้ว่าจะมีความล้มเหลวที่ไฟล์ที่ไม่มีนามสกุลจะคืนค่าสตริงสุดท้าย แต่ถ้าคุณทำเช่นนี้จะแก้ไขทุกสิ่ง:

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

เท่าที่ฉันจำได้ว่าsliceวิธีการอ้างถึงอาร์เรย์มากกว่าสตริง สำหรับสตริงsubstrหรือsubstringจะทำงาน
VisioN

@VisioN แต่ฉันเดาว่าคุณควรรู้ว่ามีString.prototype.sliceและยังArray.prototype.sliceดังนั้นมันทั้งสองวิธีการทำงานชนิดของวิธีการ
ฮุสเซน Nazzal

1
อ่าใช่ คุณพูดถูก ลืมวิธีการนี้โดยสิ้นเชิง ความผิดฉันเอง.
VisioN

5

ฉันแน่ใจว่าใครบางคนสามารถและจะลดขนาดและ / หรือเพิ่มประสิทธิภาพรหัสของฉันในอนาคต แต่ ณตอนนี้ฉันมั่นใจ 200% ว่าโค้ดของฉันใช้ได้ในทุกสถานการณ์ที่ไม่ซ้ำกัน (เช่นมีเพียงชื่อไฟล์เท่านั้นกับญาติ , รากญาติและแน่นอนของ URL มีส่วน #แท็กด้วยแบบสอบถาม ?สตริงและสิ่ง ไม่อย่างนั้นคุณอาจตัดสินใจโยนมัน) ไร้ที่ติและด้วยความแม่นยำระดับพิน

สำหรับหลักฐานการเยี่ยมชม: https://projects.jamesandersonjr.com/web/js_projects/get_file_extension_test.php

นี่คือ JSFiddle: https://jsfiddle.net/JamesAndersonJr/ffcdd5z3/

ไม่ใช่เพื่อความมั่นใจหรือเป่าทรัมเป็ตของตัวเอง แต่ฉันไม่ได้เห็นบล็อคของรหัสใด ๆสำหรับงานนี้ (การหานามสกุลไฟล์'ถูกต้อง'ท่ามกลางแบตเตอรี่ของfunctionอาร์กิวเมนต์ที่ต่างกัน) ซึ่งทำงานได้ดีเช่นนี้

หมายเหตุ:จากการออกแบบหากไม่มีนามสกุลไฟล์สำหรับอินพุตสตริงที่กำหนดมันจะส่งคืนสตริงว่างเปล่า""ไม่ใช่ข้อผิดพลาดหรือข้อความแสดงข้อผิดพลาด

มันต้องใช้สองข้อโต้แย้ง:

  • สตริง: fileNameOrURL (อธิบายตนเอง)

  • บูลีน: showUnixDotFiles (แสดงหรือไม่แสดงไฟล์ที่ขึ้นต้นด้วยจุด ".")

หมายเหตุ (2):ถ้าคุณชอบรหัสของฉันอย่าลืมเพิ่มลงในห้องสมุด js ของคุณและ / หรือ repo ของเพราะฉันทำงานหนักในการปรับปรุงมันให้สมบูรณ์และมันน่าละอายที่จะต้องเสีย ดังนั้นโดยไม่ต้องกังวลใจเพิ่มเติมนี่คือ:

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

สนุก! คุณค่อนข้างยินดีต้อนรับ!:


1
น่ากลัว ขอบคุณ!
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

หากคุณกำลังจัดการกับ URL ของเว็บคุณสามารถใช้:

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

การสาธิต: https://jsfiddle.net/squadjot/q5ard4fj/


ฉันชอบทางออกของคุณจริงๆ มันทำได้น้อยมากด้วย ฉันจะใช้มัน
Jules Manson

4

ลองสิ่งนี้:

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

แก้ไข: แปลก (หรืออาจจะไม่ใช่) $1ในอาร์กิวเมนต์ที่สองของวิธีการแทนที่ดูเหมือนจะไม่ทำงาน ... ขออภัย


1
มันใช้งานได้ดี แต่คุณพลาดไปว่าคุณจะต้องลบเนื้อหาอื่น ๆ ของสตริง: return filename.replace (/^.*? \ \ ([a-zA-Z0-9] +) $ /, "$ 1");
roenving

3

ฉันเพิ่งรู้ว่ามันไม่เพียงพอที่จะแสดงความคิดเห็นในคำตอบของ p4bl0 แต่คำตอบของ Tom แก้ปัญหาได้อย่างชัดเจน:

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

3

สำหรับแอปพลิเคชันส่วนใหญ่สคริปต์ง่ายๆเช่น

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

จะทำงานได้ดี (ตามที่ทอมจัดหาให้) อย่างไรก็ตามนี่ไม่ใช่ข้อพิสูจน์ที่โง่เขลา มันไม่ทำงานหากมีการระบุชื่อไฟล์ต่อไปนี้:

image.jpg?foo=bar

อาจเป็น overkill เล็กน้อย แต่ฉันขอแนะนำให้ใช้ parser url เช่นนี้เพื่อหลีกเลี่ยงความล้มเหลวเนื่องจากชื่อไฟล์ที่ไม่แน่นอน

เมื่อใช้ฟังก์ชั่นเฉพาะนั้นคุณจะได้รับชื่อไฟล์ดังนี้:

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

สิ่งนี้จะเอาท์พุต "image.jpg" โดยไม่มี url vars จากนั้นคุณมีอิสระที่จะคว้าส่วนขยายของไฟล์


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

// การใช้งาน

ส่วนขยาย ( 'file.jpeg')

คืนค่า cas ล่างที่ต่ำกว่าเสมอเพื่อให้คุณสามารถตรวจสอบได้ว่าการเปลี่ยนแปลงในฟิลด์นั้นสามารถทำงานได้สำหรับ:

file.JpEg

ไฟล์ (ไม่มีนามสกุล)

ไฟล์. (noextension)


3

หากคุณกำลังมองหาส่วนขยายที่เฉพาะเจาะจงและทราบความยาวของมันคุณสามารถใช้substr :

var file1 = "50.xsl";

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

การอ้างอิง JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr


1
ความงามมาพร้อมกับความเรียบง่าย นี่คือคำตอบที่ฉลาดฉลาดและมีประสิทธิภาพมากขึ้นสำหรับทุกคน ฉันมักจะใช้ String.substr (-3) หรือ String.substr (-4) เพื่อคว้าส่วนขยายในระบบที่ใช้ Windows ทำไมบางคนต้องการใช้นิพจน์ทั่วไปและลูปแบบบ้าคลั่งสำหรับสิ่งนั้น
asiby

13
@asiby การแก้ปัญหาประเภทนี้เป็นสาเหตุหลักที่ทำให้จรวดอวกาศหยุดทำงานหลังจากเปิดตัว
VisioN

3

ฉันไปดวงจันทร์หลายสายถึงงานปาร์ตี้ แต่เพื่อความเรียบง่ายฉันใช้บางอย่างเช่นนี้

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

มีฟังก์ชันไลบรารีมาตรฐานสำหรับสิ่งนี้ในpathโมดูล:

import path from 'path';

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

เอาท์พุท:

.txt

ดังนั้นหากคุณต้องการรูปแบบ:

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

หากไม่มีส่วนขยายฟังก์ชันจะส่งคืนสตริงว่าง:

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

หากคุณใช้ Node แสดงว่าpathมีอยู่แล้ว หากคุณกำหนดเป้าหมายเบราว์เซอร์ Webpack จะรวมการpathใช้งานสำหรับคุณ หากคุณกำหนดเป้าหมายเบราว์เซอร์ที่ไม่มี Webpack คุณสามารถรวมพา ธเบราว์เซอร์ด้วยตนเองได้

ไม่มีเหตุผลที่จะทำการแยกสตริงหรือ regex


ใครพูดอะไรเกี่ยวกับโหนด
แชนนอน Hochkins

ข้อโต้แย้งของคุณที่ไม่ได้ใช้การแยกหรือการแสดงออกปกติคือการรวมปลั๊กอินหรือมัดแอปพลิเคชันกับโหนดมันเป็นคำตอบที่ดีที่สุดสำหรับงานที่ไม่อยู่กับงาน
Shannon Hochkins

@ShannonHochkins ส่วนใหญ่เวลาที่คุณมีสิ่งเหล่านี้ตั้งอยู่แล้ว
sdgfsdh

@AndreiDraganescu ฉันไม่ได้ตั้งใจที่จะวางตัวดังนั้นได้กระชับลง
sdgfsdh

3

"หนึ่งซับ" เพื่อรับชื่อไฟล์และส่วนขยายโดยใช้reduceและการทำลายอาร์เรย์ :

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

ด้วยการเยื้องที่ดีกว่า:

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

สิ่งนี้ไม่ทำงานใน IE 11
Gokul Maha

คุณสามารถใช้ babel / typescript / polyfills สำหรับฟีเจอร์ ES7 + ที่หายไปของ IE 11
boehm_s

2

โซลูชันบรรทัดเดียวที่จะอธิบายพารามิเตอร์การสืบค้นและอักขระใด ๆ ใน 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)หากไฟล์ไม่มีนามสกุลไฟล์จะยังคงส่งคืนชื่อไฟล์ (2)หากมีแฟรกเมนต์ใน URL แต่ไม่มีเคียวรี (เช่นpage.html#fragment) สิ่งนี้จะส่งคืนนามสกุลไฟล์และแฟรกเมนต์
แจ็ค

2

วิธีแก้ปัญหาง่ายๆนี้

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

การทดสอบ

/* 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

คำตอบของ Wallacer นั้นดี แต่จำเป็นต้องมีการตรวจสอบอีกครั้ง

หากไฟล์ไม่มีนามสกุลไฟล์จะใช้ชื่อไฟล์เป็นนามสกุลที่ไม่ดี

ลองอันนี้:

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

1

อย่าลืมว่าไฟล์บางไฟล์ไม่มีส่วนขยายดังนั้น:

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
ในขณะที่ข้อมูลโค้ดนี้อาจแก้ไขคำถามรวมถึงคำอธิบายช่วยปรับปรุงคุณภาพของโพสต์ของคุณ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและคนเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำรหัสของคุณ
Brett DeWoody
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.