Как я могу получить расширения файлов с помощью JavaScript?

См. Код:

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

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

Ответ 1

Новое редактирование: Многие вещи изменились с тех пор, как этот вопрос был изначально опубликован - есть много действительно хорошей информации в пересмотренный ответ wallacer а также отличная разбивка VisioN


Изменить: Только потому, что это принятый ответ; ответ wallacer действительно намного лучше:

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

Мой старый ответ:

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

Должно это сделать.

Изменить: В ответ на комментарий PhiLho используйте что-то вроде:

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

Ответ 2

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

Держите это просто:)

Edit:

Это другое нерепрессивное решение, которое, по моему мнению, более эффективно:

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

Есть некоторые угловые случаи, которые лучше обрабатываются ответом VisioN ниже, особенно файлы без расширения (.htaccess и т.д.).

Он очень эффективен и обрабатывает угловые случаи, пожалуй, лучше, возвращая "" вместо полной строки, когда нет точки или нет строки перед точкой. Это очень хорошо разработанное решение, хотя и трудночитаемое. Вставьте его в свои помощники lib и просто используйте его.

Old Edit:

Более безопасная реализация, если вы собираетесь запускать файлы без расширения или скрытые файлы без расширения (см. комментарий VisioN для ответа Тома выше) будет что-то в этом направлении

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

Надеемся, что это поможет устранить проблемы со слегка более сложными делами. Что касается производительности, я считаю, что это решение немного медленнее, чем регулярное выражение в большинстве браузеров. Тем не менее, для большинства распространенных целей этот код должен быть полностью работоспособен.

Ответ 3

Следующее решение быстро и короткое достаточно для использования в массовых операциях и сохранения дополнительных байтов:

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

Вот еще одно однострочное универсальное решение без регулярного выражения:

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

Оба работают правильно с именами, не имеющими расширения (например, myfile), или начиная с . dot (например .htaccess):

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

Если вам нужна скорость, вы можете запустить benchmark и убедиться, что предоставленные решения являются самыми быстрыми, а короткий - чрезвычайно быстро:

Speed comparison

Как работает короткий:

  • String.lastIndexOf метод возвращает последнюю позицию подстроки (т.е. ".") в данной строке (т.е. fname). Если метод substring не найден, возвращается -1.
  • "Недопустимые" позиции точки в имени файла -1 и 0, которые соответственно относятся к именам без расширения (например, "name") и именам, начинающимся с точки (например, ".htaccess").
  • Оператор сдвига нулевого заполнения (>>>), если используется с нулем, влияет на отрицательные числа, преобразуя -1 в 4294967295 и -2 до 4294967294, что полезно для сохранения имени файла без изменений в случаях краев (вроде трюка здесь).
  • String.prototype.slice извлекает часть имени файла из позиции, которая была рассчитана, как описано. Если номер позиции больше, чем длина метода string возвращает "".

Если вы хотите более четкое решение, которое будет работать одинаково (плюс с дополнительной поддержкой полного пути), проверьте следующую расширенную версию. Это решение будет медленнее, чем предыдущие однострочные, но гораздо легче понять.

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 на стороне сервера.

Ответ 4

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

Ответ 5

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

Ответ 6

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

Ответ 7

var parts = filename.split('.');
return parts[parts.length-1];

Ответ 8

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

Ответ 9

Быстро и правильно работает с путями

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

Некоторые краевые случаи

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

Решения, использующие split, медленны, а решения с lastIndexOf не обрабатывают случаи ребер.

Ответ 10

код

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

Test

Обратите внимание, что в отсутствие запроса фрагмент все еще может присутствовать.

"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 Предупреждения.

Ответ 11

Попробуйте следующее:

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

Ответ 12

Я просто хотел поделиться этим.

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

хотя это имеет падение, что файлы без расширения вернут последнюю строку. но если вы это сделаете, это зафиксирует все:

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

Ответ 13

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

edit: Странно (или, может быть, нет) $1 во втором аргументе метода replace, похоже, не работает... Извините.

Ответ 14

Я только понял, что этого недостаточно, чтобы пометить ответ p4bl0, хотя ответ Tom четко решает проблему:

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

Ответ 15

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

всегда возвращает нижний предел расширения, чтобы вы могли проверить его при изменении поля работает для:

file.JpEg

(без расширения)

файл. (Noextension)

Ответ 16

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

Ответ 17

Для большинства приложений простой script, например

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

будет работать отлично (как сообщил Том). Однако это не является доказательством дурака. Он не работает, если предусмотрено следующее имя файла:

image.jpg?foo=bar

Это может быть немного избыточно, но я бы предложил использовать парсер url, например этот, чтобы избежать сбоя из-за непредсказуемых имен файлов.

Используя эту конкретную функцию, вы можете получить имя файла следующим образом:

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

Это будет выводить "image.jpg" без url-варов. Затем вы можете захватить расширение файла.

Ответ 19

У меня много спутников на вечеринке, но для простоты я использую что-то вроде этого

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>

Ответ 20

Однострочное решение, которое будет также учитывать параметры запроса и любые символы в URL.

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

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

Ответ 21

Ответ Wallacer хорош, но нужна еще одна проверка.

Если файл не имеет расширения, он будет использовать имя файла как расширение, которое не является хорошим.

Попробуйте следующее:

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

Ответ 22

Не забывайте, что некоторые файлы не имеют расширения, поэтому:

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

Ответ 23

Это простое решение

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

Ответ 24

Я уверен, что кто-то сможет, и будет, минимизировать и/или оптимизировать мой код в будущем. Но на данный момент я на 200% уверен, что мой код работает в каждой уникальной ситуации (например, только с именем файла, с относительным, корневым и абсолютным URL-адресом, с тегами фрагмента # с запросом ?, и что бы вы ни выбрали для этого), безупречно и с точными точками.

Для доказательства посетите: https://projects.jamesandersonjr.com/web/js_projects/get_file_extension_test.php

Здесь JSFiddle: https://jsfiddle.net/JamesAndersonJr/ffcdd5z3/

Не быть слишком самоуверенным или дуть собственной трубой, но я не видел блок кода для этой задачи (нахождение "правильного" расширения файла среди батареи с различными входными аргументами function), которая работает как хорошо, как это делает.

Примечание. По дизайну, если расширение файла не существует для данной входной строки, оно просто возвращает пустую строку "", а не ошибку или сообщение об ошибке.

Требуется два аргумента:

  • String: fileNameOrURL (самоочевидно)

  • Boolean: showUnixDotFiles (показывать или не показывать файлы, начинающиеся с точки "." )

Примечание (2): Если вам нравится мой код, обязательно добавьте его в библиотеку js и/или репо, потому что я много работал над его совершенствованием, и было бы позором идти впустую. Итак, без дальнейших церемоний, вот он:

function getFileExtension(fileNameOrURL, showUnixDotFiles)
    {
        /* First, let 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 take advantage of the browser 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 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 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 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 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 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 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 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 return it to the function caller. */
        return fileExt;
    };

Наслаждайтесь! Добро пожаловать!

Ответ 25

Если вы имеете дело с веб-адресами, вы можете использовать:

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

getExt("logic.v2.min.js") // js
getExt("http://example.net/site/page.php?id=16548") // php
getExt("http://example.net/site/page.html#welcome") // html

Демо: https://jsfiddle.net/squadjot/q5ard4fj/

Ответ 26

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

Ответ 27

var filetypeArray = (file.type).split("/");
var filetype = filetypeArray[1];

Это лучший подход imo.

Ответ 28

В node.js это может быть достигнуто с помощью следующего кода:

var file1 ="50.xsl";
var path = require('path');
console.log(path.parse(file1).name);

Ответ 29

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

Ответ 30

Я предпочитаю использовать lodash для большинства вещей, так что вот решение:

function getExtensionFromFilename(filename) {
    let extension = '';
    if (filename > '') {
        let parts = _.split(filename, '.');
        if (parts.length >= 2) {
        extension = _.last(parts);
    }
    return extension;
}