問題:如何取得檔案的副檔名?

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

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

解決方案一:正規表達式

function getFileExtension1(filename) {
  return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename)[0] : undefined;
}

解決方案二:String 的 split 方法

function getFileExtension2(filename) {
  return filename.split('.').pop();
}

那些兩個解決方案不能處理一些邊緣情況,這裡是另一個更好的解決方案。

解決方案三:String 的 slicelastIndexOf 方法

function getFileExtension3(filename) {
  return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
}

console.log(getFileExtension3(''));                            // ''
console.log(getFileExtension3('filename'));                    // ''
console.log(getFileExtension3('filename.txt'));                // 'txt'
console.log(getFileExtension3('.hiddenfile'));                 // ''
console.log(getFileExtension3('filename.with.many.dots.ext')); // 'ext'

它是如何處理的呢?

  • String.lastIndexOf() 方法回傳最後一個符合指定的值(在範例中的 '.')。如果找不到值則回傳 -1
  • 對於參數 'filename''.hidden'lastIndexOf 的回傳值,分別為 01無符號右移運算子(»>) 會將 -1 轉換成 4294967295 和將 -2 轉換成 4294967294,這裡是一個小技巧來確保在邊緣情況下檔案名稱不會改變。
  • String.prototype.slice() 從上面計算的索引中提取檔副檔名。如果索引超過檔案的長度,那結果會是 ""

比較

解決方案 參數 結果
解決方案一:正規表達式 ’‘
‘filename’
‘filename.txt’
‘.hiddenfile’
‘filename.with.many.dots.ext’
undefined
undefined
‘txt’
‘hiddenfile’
‘ext’
解決方案二:String 的 split 方法 ’‘
‘filename’
‘filename.txt’
‘.hiddenfile’
‘filename.with.many.dots.ext’
’’
‘filename’
‘txt’
‘hiddenfile’
‘ext’
解決方案三:String 的 slicelastIndexOf 方法 ’‘
‘filename’
‘filename.txt’
‘.hiddenfile’
‘filename.with.many.dots.ext’
’’
‘’
‘txt’
‘’
‘ext’

實際範例和效能

這裡是上方程式碼的實際範例。

這裡是三個解決方案的效能測試。

來源

如何使用 JavaScript 來取得檔案副檔名