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

502

Смотрите код:

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

function getFileExtension(filename) {
    /*TODO*/
}
Серхио дель Амо
источник

Ответы:

796

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


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

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

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

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

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

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

return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined;
Том
источник
1
Разве это не дорого, чтобы выполнить регулярное выражение дважды?
Эндрю Хеджес
5
Высоко оцененный ответ ниже намного лучше.
Флет
2
К сожалению, оба решения не подходят для таких имен, как file и .htaccess .
VisioN
3
Все возможные случаи обрабатываются следующим образом: return filename.split ("."). Slice (1) .pop () || "";
JustAndrei
1
@JustAndrei Еще не все :) Для чистого имени файла (базовое имя?), А не для пути, по практическим соображениям, я думаю, что это должно быть. return filename.substring(0,1) === '.' ? '' : filename.split('.').slice(1).pop() || '';Это также заботится о .file(Unix скрытых, я считаю) видах файлов. То есть, если вы хотите сохранить его как одну строчку, на мой вкус, это немного грязно.
Кукер
833
return filename.split('.').pop();

Будь проще :)

Редактировать:

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

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

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

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

Старый Править:

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

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

wallacer
источник
4
Я не могу комментировать представление, но этот, безусловно, выглядит чисто! Я использую это. +1
pc1oad1etter
6
но в этом случае имя файла выглядит как filname.tes.test.jpg. Пожалуйста, рассмотрите выход. Я надеюсь, что это будет ложным.
Fero
19
в этом случае вывод будет "JPG"
Wallacer
1
Brilliant! Огромное спасибо. Приятно видеть решение, не использующее регулярные выражения; Я сделал это с помощью PHP, и он использует только несколько функций. +1
Bojangles
3
@wallacer: Что произойдет, если на filenameсамом деле не имеет расширения? Разве это не просто возвращает базовое имя файла, что было бы довольно плохо?
Николь Болас
288

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

 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"

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

Сравнение скорости

Как работает короткая

  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
34
@mrbrdo Этот метод не должен работать с полным путем только с именами файлов, как того требует вопрос. Внимательно прочитайте вопрос, прежде чем голосовать.
VisioN
8
Зачем идти на все, чтобы оптимизировать такую ​​тривиальную строку кода? Операторы тильды и битового сдвига настолько редко встречаются в JavaScript, что я не могу поддержать такой ответ. Если для объяснения того, как работает 1 строка кода, требуется 5 пунктов, лучше переписать код, чтобы он был понятен.
Джексон
6
Скорость этой одной линии не будет иметь никакого значения в любом приложении. Битовое шифрование используется так редко, что популярные линтеры, такие как JSLint и JSHint, предостерегают от их использования. Ощущение производительности и компактности этой логики ухудшило качество кода; если код требует «дополнительного расследования», я считаю его «плохим».
Джексон
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")
PhiLho
источник
Чтобы это работало в IE: var pattern = "^. + \\. ([^.] +) $"; var ext = new RegExp (pattern);
spc16670
20
function getExt(filename)
{
    var ext = filename.split('.').pop();
    if(ext == filename) return "";
    return ext;
}
Дима
источник
8
вернуть (ext === имя файла)? '': ext;
Michiel
13
var extension = fileName.substring(fileName.lastIndexOf('.')+1);
Pono
источник
8
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;
    }
Джо Сцилла
источник
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 не обрабатывают крайние случаи.

mrbrdo
источник
Какие крайние случаи вы имеете в виду? Пожалуйста, обратитесь к моему решению здесь: stackoverflow.com/a/12900504/1249581 . Он работает хорошо во всех случаях и намного быстрее, чем любой регулярное выражение.
VisioN
Я уже перечислил крайние случаи. И ваше решение НЕ обрабатывает их должным образом. Как я уже писал, попробуйте "/dir.with.dot/file". Ваш код возвращает «точка / файл», что смехотворно неправильно.
mrbrdo
1
Никто не просил разобрать путь. Вопрос заключался в извлечении расширений из имен файлов.
VisioN
3
Как я уже говорил вам, об этом никогда не говорилось явно, и решение, которое обрабатывает пути, очевидно, гораздо более полезно. Предполагается, что ответ на вопрос о SO будет полезен для других людей, кроме человека, который задал вопрос. Я действительно не думаю, что решение, которое обрабатывает множество входных данных, должно быть отвергнуто.
mrbrdo
3
Понижение было за использование глобальной переменной с .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другое, что-то вроде метода работы
Хусейн Наззал
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 (не требует пояснений)

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

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

Джеймс Андерсон младший
источник
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/

Якоб Штернберг
источник
Мне очень нравится ваше решение. Это так много делает с таким небольшим. Я собираюсь использовать это.
Жюль Мэнсон
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во втором аргументе метода замены, кажется, не работает ... Извините.

p4bl0
источник
1
Он отлично работает, но вы пропустили, что вам придется удалить все остальное содержимое строки: return filename.replace (/^.*? \. ([A-zA-Z0-9] +) $ /, "$ 1");
Реннинг
3

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

return filename.replace(/^.*?\.([a-zA-Z0-9]+)$/, "$1");
roenving
источник
3

Для большинства приложений используется простой скрипт, такой как

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

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

image.jpg?foo=bar

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

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

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

Это выведет "image.jpg" без изменения URL. Тогда вы можете получить расширение файла.

Джастин бык
источник
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>

DzSoundNirvana
источник
3

Для этого в pathмодуле есть стандартная библиотечная функция :

import path from 'path';

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

Вывод:

.текст

Итак, если вы хотите только формат:

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

Если расширения нет, функция вернет пустую строку:

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

Если вы используете Node, то pathвстроенный. Если вы ориентируетесь на браузер, то Webpack поставит pathвам реализацию. Если вы нацеливаетесь на браузер без Webpack, то вы можете включить path-browserify вручную.

Нет причин делать разбиение строк или регулярное выражение.

sdgfsdh
источник
Кто сказал что-нибудь об узле?
Шеннон Хохкинс,
Ваш аргумент в пользу того, чтобы не использовать расщепление или регулярные выражения, состоит в том, чтобы включить плагин или связать приложение с узлом, это чрезмерный ответ для
сложной
@ShannonHochkins в большинстве случаев вы все равно
настраиваете
@AndreiDraganescu Я не хотел, чтобы это было снисходительным, поэтому смягчил это.
sdgfsdh
3

"one-liner" для получения имени файла и расширения с использованием 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"
// }
boehm_s
источник
Это не работает в IE 11
Гокул Маха
Вы можете использовать babel / typcript / 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
Labithiotis
источник
(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;
}

Vitim.us
источник
1

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

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

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

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
Хотя этот фрагмент кода может решить вопрос, в том числе объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин, по которым вы предлагаете код.
Бретт ДеВуди,