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


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

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

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

30 ответов:

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


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

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

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

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

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

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

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

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

Edit:

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

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

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

это очень эффективно, и обрабатывает угловые случаи, возможно, лучше, возвращая "" вместо полной строки, когда перед точкой нет ни точки, ни строки. Это очень хорошо продуманное решение, хотя и трудно читать. Вставьте его в свой помощник 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. file

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

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

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

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

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

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

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

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

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-адрес Варс. Тогда вы можете захватить расширение файла.

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

/ / usage

расширение ('file.jpeg')

всегда возвращает расширение ниже 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 хорош, но требуется еще одна проверка.

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

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

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

Demo:https://jsfiddle.net/squadjot/q5ard4fj/

fetchFileExtention(fileName) {
    return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2);
}
var filetypeArray = (file.type).split("/");
var filetype = filetypeArray[1];

Это лучше, ИМО.

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

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