Как я могу получить расширения файлов с помощью 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-варов. Затем вы можете захватить расширение файла.
Ответ 18
Если вы ищете конкретное расширение и знаете его длину, вы можете использовать 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
Ответ 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;
}