Как я могу получить расширения файлов с помощью JavaScript? - PullRequest
421 голосов
/ 10 октября 2008

См. Код:

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

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

Ответы [ 33 ]

751 голосов
/ 30 июля 2009
return filename.split('.').pop();

Будьте проще :)

Edit:

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

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

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

665 голосов
/ 10 октября 2008

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


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

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

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

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

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

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

return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined;
255 голосов
/ 15 октября 2012

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

 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"

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

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

26 голосов
/ 10 октября 2008
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")
19 голосов
/ 27 октября 2011
function getExt(filename)
{
    var ext = filename.split('.').pop();
    if(ext == filename) return "";
    return ext;
}
13 голосов
/ 23 ноября 2011
var extension = fileName.substring(fileName.lastIndexOf('.')+1);
8 голосов
/ 09 июля 2016

Код

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

8 голосов
/ 10 октября 2008
function file_get_ext(filename)
    {
    return typeof filename != "undefined" ? filename.substring(filename.lastIndexOf(".")+1, filename.length).toLowerCase() : false;
    }
8 голосов
/ 10 октября 2008
var parts = filename.split('.');
return parts[parts.length-1];
6 голосов
/ 30 сентября 2013

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

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

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

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

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

...