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

посмотреть код:

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

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

30 ответов


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


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

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

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

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

должны сделать он.

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

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

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

сохранить его простым :)

Edit:

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

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

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

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

Старый Редактирование:

более безопасная реализация, если вы собираетесь запускать файлы без расширения или скрытые файлы без расширения (см. комментарий 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 один, это видимый файл без расширения ie.

если a[0] === "" и a.length === 2 это скрытый файл без расширения ie. .реврайт

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


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

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

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

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

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

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

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

Speed comparison

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

  1. String.lastIndexOf метод возвращает последнюю позицию подстроки (т. е. ".") в данной строке (т. е. fname). Если подстрока не найдена, метод возвращает -1.
  2. "неприемлемой" позицию точка в имени файла -1 и 0, которые соответственно ссылаются на имена без расширения (например,"name") и к именам, которые начинаются с точки (например,".htaccess").
  3. оператор сдвига вправо с нулевым заполнением (>>>) при использовании с нулем влияет на преобразование отрицательных чисел -1 to 4294967295 и -2 to 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 на стороне сервера.


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

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

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

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

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

код

/**
 * 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 предупреждений.


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

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

в некоторых случаях

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

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


попробуйте это:

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

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

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

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

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

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

edit: странно (или, может быть, это не так) во втором аргументе метода replace не работает... Извиняюсь.


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

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

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

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

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

image.jpg?foo=bar

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

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

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

это выведет " изображение.jpg " без url vars. Тогда вы можете захватить расширение файла.


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

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

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

.В формате JPEG (без расширения) . (noextension)

Если вы ищете конкретное расширение и знаете его длину, вы можете использовать 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


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

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>

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

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

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

ответ Wallacer хорош, но необходима еще одна проверка.

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

попробуй это:

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

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

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

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

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

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

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

вот JSFiddle:https://jsfiddle.net/JamesAndersonJr/ffcdd5z3/

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

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

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

  • строку: fileNameOrURL (само собой разумеется)

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

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

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

наслаждайтесь! Всегда пожалуйста!:


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

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/


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

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

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


в узел.js, это может быть достигнуто следующим кодом:

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

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

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

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