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