Смотрите код:
var file1 = "50.xsl";
var file2 = "30.doc";
getFileExtension(file1); //returns xsl
getFileExtension(file2); //returns doc
function getFileExtension(filename) {
/*TODO*/
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


return filename.replace(/\.([a-zA-Z0-9]+)$/, "");
edit: Странно (или, может быть, это не так), во втором аргументе метода замены, похоже, не работает ... Извините.
Новое редактирование: Многое изменилось с тех пор, как этот вопрос был первоначально опубликован - в исправленный ответ Wallacer, а также в Отличный анализ VisioN есть много действительно хорошей информации
Редактировать: Просто потому, что это принятый ответ; ответ Wallacer действительно намного лучше:
return filename.split('.').pop();
Мой старый ответ:
return /[^.]+$/.exec(filename);
Должен это сделать.
Редактировать: В ответ на комментарий PhiLho используйте что-то вроде:
return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined;
Разве не дорого выполнять регулярное выражение дважды?
лучше использовать регулярное выражение, чем lastindexof? благодаря.
Высоко оцененный ответ ниже намного лучше.
К сожалению, оба решения не подходят для таких имен, как файл и .htaccess.
regexp, вероятно, быстрее, чем разбиение на массив, чтобы получить последнее значение
Все возможные случаи обрабатываются следующим образом: return filename.split ("."). Slice (1) .pop () || "";
@JustAndrei Еще не все :) Для чистого имени файла (базового имени?), А не пути, по практическим соображениям, я думаю, что это должно быть return filename.substring(0,1) === '.' ? '' : filename.split('.').slice(1).pop() || '';. Это также касается файлов типа .file (Unix, я считаю, скрытый). То есть, если вы хотите сохранить его как однострочник, что на мой вкус немного беспорядочно.
С таким именем файла, как path / to / file.png? V1.4.1, это не сработает!
Добавлен еще один ответ, который будет учитывать параметры запроса: stackoverflow.com/a/35526475/1872133
Плохое решение. Как уже указали несколько пользователей, возвращает имя файла, если у него нет расширения.
Лучше просто использовать модуль pathstackoverflow.com/a/52738209/1256041
Плюс один от меня, потому что вы упомянули лучший ответ
есть небольшая проблема со сплитом. Если вы используете (по какой-либо причине) jquery, он станет медленным из-за того, что jquery пытается самостоятельно обработать split (). В этом случае ответы другого лайнера будут быстрее. Например. используйте один вкладыш без разделения.
var parts = filename.split('.');
return parts[parts.length-1];
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")
Чтобы заставить его работать в IE: var pattern = "^. + \\. ([^.] +) $"; var ext = new RegExp (шаблон);
function file_get_ext(filename)
{
return typeof filename != "undefined" ? filename.substring(filename.lastIndexOf(".")+1, filename.length).toLowerCase() : false;
}
Я просто понял, что недостаточно просто прокомментировать ответ p4bl0, хотя ответ Тома явно решает проблему:
return filename.replace(/^.*?\.([a-zA-Z0-9]+)$/, "");
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, чтобы вы могли проверить его при изменении поля работает на:
file.JpEg
файл (без расширения)
файл. (без расширения)
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");
}
}
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
Надеюсь, это поможет прояснить проблемы с чуть более сложными случаями. Что касается производительности, я считаю, что это решение немного медленнее, чем регулярное выражение в большинстве браузеров. Однако для наиболее распространенных целей этот код должен идеально подходить для использования.
Я не могу комментировать производительность, но этот, безусловно, выглядит чистым! Я этим пользуюсь. +1
но в этом случае имя файла выглядит как filename.teas.test.jpg. Пожалуйста, рассмотрите вывод. Надеюсь, это будет неправда.
в этом случае вывод будет "jpg"
Блестяще! Огромное спасибо. Приятно видеть решение, не использующее регулярное выражение; Я сделал это с помощью PHP, и он использует только несколько функций. +1
@wallacer: Что произойдет, если у filename на самом деле нет расширения? Разве это не вернет просто базовое имя файла, что было бы неплохо?
Можно подумать о том, чтобы добавить .toLowerCase () в конец.
@NicolBolas, да, будет. Это была самая простая реализация без регулярных выражений, о которой я мог подумать примерно за 5 секунд около 2 лет назад. Хотя, похоже, помогает людям :) Он определенно должен быть взбудоражен небольшой обработкой ошибок, более низким корпусом и т. д. Для реального использования.
Опечатка в разделе "Правка". Должен быть var a = filename.split(".");
не работает для "/home/user/.app/config" (даже с "улучшенной" версией).
@mrbrdo Правдивая история - я предполагаю, что filename.split ('/'). pop (). split ('.'). pop () будет обрабатывать абсолютные пути. Хороший улов! ;)
Я предложил решение с регулярным выражением, которое также обрабатывает этот случай. Я думаю, что регулярные выражения - очевидное решение этой проблемы, поскольку это умеренно сложная проблема синтаксического анализа строк.
Да, с моим решением я не предполагаю, что регулярное выражение - это не лучший способ. Это было много лет назад, и было только несколько полусложных регулярных выражений, и я подумал, что выброшу простое решение без регулярных выражений, которое охватывает простые случаи.
@wallacer К сожалению, ваше новейшее решение не работает с файлами, начинающимися с точки, например .htaccess и файлы, не имеющие вообще никакого расширения. Это была основная причина, по которой я использовал более сложную логику в своем ответе.
@VisioN Хорошо, спасибо, что указали на это! Я обновил свой ответ, рекомендуя ваше блестящее решение.
С таким именем файла, как path / to / file.png? V1.4.1, это не сработает!
@julmot, какое расширение вы ожидаете от этого файла? .png? Вы пытаетесь использовать строку запроса, потому что она больше похожа на file.png? V = 1.4.1. Если вы храните файлы с именами типа "file.png? V1.4.1" и ожидаете, что ваша файловая система будет обрабатывать их как файлы .png, у вас, мой друг, дела пойдут не так хорошо. Да, если у вас есть какой-то странный вариант использования, выходящий за рамки нормальности, тогда конечно, этот алгоритм не читает ваши мысли и не извлекает .png из середины строки. Совершенно ясно, что он делает. Если это не то, что вам нужно, используйте что-нибудь другое.
Если вы создаете новое имя файла и хотите извлечь расширение, чтобы прикрепить его к другому базовому имени, тогда полезно иметь расширение "." но только если расширение существует. Так что измените 2 на 1, и вы можете сделать newname = newbase + fname.substr ((~ -fname.lastIndexOf (".") >>> 0) + 1); Не нужно возиться с условным добавлением точки.
Ржу не могу. Как вы, ребята, можете найти такой ответ? Без расширения -> вы получаете имя файла ... плохо, плохо ...
Это не сработает для путей. Например 'http:://someurl.com/file.png?user_token=some.hash.with.dot'
Для большинства приложений простой сценарий, например
return /[^.]+$/.exec(filename);
будет работать нормально (как предусмотрено Томом). Однако это не доказательство от дурака. Это не сработает, если указано следующее имя файла:
image.jpg?foo=bar
Это может быть немного излишним, но я бы предложил использовать парсер URL-адресов, такой как Вот этот, чтобы избежать сбоя из-за непредсказуемых имен файлов.
Используя эту конкретную функцию, вы можете получить такое имя файла:
var trueFileName = parse_url('image.jpg?foo=bar').file;
Это выведет "image.jpg" без переменных URL. Тогда вы можете получить расширение файла.
Попробуй это:
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;
}
function getExt(filename)
{
var ext = filename.split('.').pop();
if (ext == filename) return "";
return ext;
}
return (ext === filename)? '': доб;
var extension = fileName.substring(fileName.lastIndexOf('.')+1);
Следующее решение - быстрый и короткая, достаточное для использования в массовых операциях и экономии дополнительных байтов:
return fname.slice((fname.lastIndexOf(".") - 1 >>> 0) + 2);
Вот еще одно однострочное универсальное решение без регулярных выражений:
return fname.slice((Math.max(0, fname.lastIndexOf(".")) || Infinity) + 1);
Оба работают правильно с именами, не имеющими расширения (например, мой файл) или начинающимися с точки . (например, .htaccess):
"" --> ""
"name" --> ""
"name.txt" --> "txt"
".htpasswd" --> ""
"name.with.many.dots.myext" --> "myext"
Если вам важна скорость, вы можете запустить ориентир и проверить, что предоставленные решения являются самыми быстрыми, а короткое - чрезвычайно быстрым:

Как работает короткий:
String.lastIndexOf возвращает последнюю позицию подстроки (т. Е. ".") в данной строке (т. Е. fname). Если подстрока не найдена, метод возвращает -1.-1 и 0, которые соответственно относятся к именам без расширения (например, "name") и к именам, начинающимся с точки (например, ".htaccess").>>>), если используется с нулем, влияет на отрицательные числа, преобразуя -1 в 4294967295 и -2 в 4294967294, что полезно для сохранения неизменного имени файла в крайних случаях (здесь вроде уловки).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.info( getExtension("/path/to/file.ext") );
// >> "ext"
Все три варианта должны работать в любом веб-браузере на стороне клиента и могут также использоваться в коде NodeJS на стороне сервера.
@Zipp Для большей понятности я добавил описание подхода и сравнение скорости, чтобы проиллюстрировать, насколько быстро решение.
"fname.substr ((~ -fname.lastIndexOf (". ") >>> 0) + 2)" дает неверное значение для ".htaccess".
@BennyNeugebauer Что не так в вашем случае? Он дает "", поскольку имя файла, начинающееся с точки (например, .htaccess или .htpasswd), не имеет расширения.
Я ожидал, что расширение будет "htaccess"? Но это вопрос мнения. Ты прав! Я просто хотел указать. :)
@BennyNeugebauer Технически .htaccess не имеет расширения, так как это является само расширение. Этому соглашению придерживаются многие библиотеки и языки программирования. Например, в Python, когда вы выполняете os.path.splitext('/path/to/.htaccess'), он возвращает "" как расширение игнорирование ведущей точки, учитывая такое имя как имя файла без расширения.
@BennyNeugebauer Однако, если вам нужно исключить это правило, просто используйте вместо него fname.substr((fname.lastIndexOf(".") >>> 0) + 1) :)
Не работает. "/home/user/.app/config" возвращает "app / config", что совершенно неверно.
@mrbrdo Этот метод не должен работать с полным путем только с именами файлов, как того требует вопрос. Внимательно прочтите вопрос, прежде чем голосовать против.
он никогда не говорил об этом прямо, и очевидно, что это делает его более полезным, если он работает на путях
@Ajit, вероятно, потому что это решение намного более новое, чем те, что вверху ... Это вопрос 5-летней давности, а этому решению всего год ... И да. Это хорошее решение
Зачем так стараться оптимизировать такую тривиальную строку кода? Операторы тильды и битового сдвига настолько редко встречаются в JavaScript, что я не могу поддержать такой ответ. Если для объяснения того, как работает 1 строка кода, требуется 5 пунктов, лучше переписать код, чтобы он был действительно понятным.
@Jackson 1) Если вы не видите и не используете операторы тильды и битового сдвига в своем коде JavaScript, у меня для вас плохие новости. 2) Если вы всегда принимаете и используете код, который вам понятен, без дополнительных исследований, то у меня также для вас плохие новости. Если вы не понимаете сложный код, это не всегда означает, что код плохой. В текущем примере более чем ясно, что этот фрагмент кода работает во много раз быстрее, чем любые другие альтернативы, что делает его идеальным для использования в массовых операциях. Также важно сделать его компактным. И есть описание для людей, которые хотят учиться.
Скорость этой одной строки не будет иметь заметного значения для любого приложения. Побитовое использование настолько редко, что популярные линтеры, такие как JSLint и JSHint, предостерегают от их использования. Одержимость производительностью и компактностью этой логики ухудшила качество кода; если код требует «дополнительного исследования», я считаю его «плохим».
@VisioN Общая проблема здесь в том, что у простой задачи должно быть простое решение. В противном случае трудно сказать, есть ли небольшие ошибки. Если вы требуете, чтобы другие читали ваш код несколько раз, прежде чем они смогут понять, почему он работает, и ваш код полон этого, никто (даже вы) не сможет обнаружить ошибки на раннем этапе. После этого ваша команда будет обречена на поиски ошибок. Без всякой выгоды. Тесты отвлекают, они просто показывают, что эта оптимизация не стоит проблем, поскольку очевидное решение уже работает на порядки быстрее, чем необходимо.
@vog Если вам не нравится код или вы считаете его бесполезным, вы можете использовать другой или реализовать собственное более простое решение, которое будет правильно работать с разными входными данными. Я лично считаю это решение работоспособным и полезным для моих нужд. Более того, я не вижу проблем в чтении описания того, как это работает, или просто игнорирую его, если вы не утруждаетесь его пониманием. Использовать это или нет - ваше решение, я просто поделился тем, что некоторые могут найти полезными.
@VisioN Я знаю, что могу не любить этот код, поэтому могу просто проигнорировать его. Но поскольку это часть публичного ответа на общественный вопрос, я почувствовал побуждение объяснить, что именно мне в нем не нравится.
А как насчет двойных удлинителей, например .tar.gz?
@ Alph.Dev Я сомневаюсь, что вы сможете найти какой-либо действующий алгоритм для различения всех типов расширений, не имея какой-либо базы данных для проверки. Кроме того, насколько я понимаю, .tar.gz не является расширением, поскольку расширение .gz для GZIP-файла с расширением .tar, который является архивом TAR.
@Jackson Учитывая, что это сайт, предлагающий несколько решений проблемы, наличие решения, которое оптимизирует производительность, никогда не бывает плохим. Ваше заявление «не будет иметь заметных различий ни в одном приложении» полностью основано на вашем узком диапазоне возможных приложений, в которых это может быть использовано. Помимо этого, оно может дать тем, кто занимается проблемой, опыт обучения, в котором они могут оптимизировать некоторые другой код, который им нужно сделать для написанного ими приложения с интенсивными вычислениями.
Я думаю, что str.length также будет работать вместо Infinity. хороший ответ кстати
Ответ Уоллесера хорош, но нужна еще одна проверка.
Если у файла нет расширения, он будет использовать имя файла как расширение, что нехорошо.
Попробуй это:
return ( filename.indexOf('.') > 0 ) ? filename.split('.').pop().toLowerCase() : 'undefined';
Не забывайте, что некоторые файлы не могут иметь расширения, поэтому:
var parts = filename.split('.');
return (parts.length > 1) ? parts.pop() : '';
Быстро и корректно работает с путями
(filename.match(/[^\/]\.([^.\/]+)$/) || [null]).pop()
Некоторые крайние случаи
/path/.htaccess => null
/dir.with.dot/file => null
Решения с использованием split работают медленно, а решения с lastIndexOf не обрабатывают крайние случаи.
Какие крайние случаи вы имеете в виду? Пожалуйста, обратитесь к моему решению здесь: stackoverflow.com/a/12900504/1249581. Он отлично работает во всех случаях и намного быстрее, чем любое регулярное выражение.
Я уже перечислил крайние случаи. И ваше решение НЕ обрабатывает их должным образом. Как я уже писал, попробуйте "/dir.with.dot/file". Ваш код возвращает «точку / файл», что до смешного неверно.
Никто не просил разбирать путь. Вопрос был в извлечении расширений из имен файлов.
Как я уже сказал вам, об этом никогда не говорилось явно, и решение, которое обрабатывает пути, очевидно, намного полезнее. Предполагается, что ответ на вопрос о SO будет полезен другим людям, помимо человека, задавшего вопрос. Я действительно не думаю, что решение, которое обрабатывает расширенный набор входных данных, должно быть отвергнуто.
Голос против был за использование глобальной переменной с .exec(). Ваш код будет лучше как (filename.match(/[^/]\.([^/.]+)$/) || [null]).pop().
Значит, вы могли бы так сказать. Глобальная переменная ускользнула от меня, так как я использую это в Coffeescript, моя проблема в этом.
я просто хотел поделиться этим.
fileName.slice(fileName.lastIndexOf('.'))
хотя это имеет недостаток, что файлы без расширения будут возвращать последнюю строку. но если вы это сделаете, это исправит все:
function getExtention(fileName){
var i = fileName.lastIndexOf('.');
if (i === -1 ) return false;
return fileName.slice(i)
}
Насколько я помню, метод slice относится к массивам, а не к строкам. Для струн substr или substring подойдет.
@VisioN, но я думаю, вы должны знать, что есть String.prototype.slice, а также Array.prototype.slice, так что это как бы оба способа работы своего рода метод
О да. Ты прав. Совершенно забыл об этом методе. Виноват.
var filetypeArray = (file.type).split("/");
var filetype = filetypeArray[1];
Имо, это лучший подход.
Если вы ищете конкретное расширение и знаете его длину, вы можете использовать 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
Красота приходит с простотой. Это самый умный, элегантный и эффективный ответ из всех. Я всегда использовал String.substr (-3) или String.substr (-4) для получения расширений в системах на базе Windows. Зачем кому-то использовать для этого регулярные выражения и сумасшедшие циклы.
@asiby Подобные решения являются основной причиной падения космических ракет после запуска.
Я опаздываю на вечеринку на много лун, но для простоты использую что-то вроде этого
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>В node.js этого можно добиться с помощью следующего кода:
var file1 = "50.xsl";
var path = require('path');
console.info(path.parse(file1).name);
Однострочное решение, которое также будет учитывать параметры запроса и любые символы в URL-адресе.
string.match(/(.*)\??/i).shift().replace(/\?.*/, '').split('.').pop()
// Example
// some.url.com/with.in/&ot.s/files/file.jpg?spec=1&.ext=jpg
// jpg
page.html#fragment), this will return the file extension and the fragment.
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
Код
/**
* 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 Предупреждения.
Не работает, если в конце есть еще одна косая черта, как что-то закодированное, например: "example.com:8080/segment1/segment2/page.html?enc=abc/def"
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.info(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), который работает так же хорошо, как это.
Примечание: По замыслу, если расширение файла не существует для данной входной строки, оно просто возвращает пустую строку "", а не ошибку или сообщение об ошибке.
It takes two arguments:
String: fileNameOrURL(self-explanatory)
Boolean: showUnixDotFiles (Whether or Not to show files that begin with a dot ".")
Заметка 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(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/
Мне очень нравится ваше решение. Он так много делает с таким малым. Я собираюсь использовать это.
fetchFileExtention(fileName) {
return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2);
}
Хотя этот фрагмент кода может решить вопрос, включая объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причины вашего предложения кода.
Я предпочитаю использовать lodash для большинства вещей, поэтому вот решение:
function getExtensionFromFilename(filename) {
let extension = '';
if (filename > '') {
let parts = _.split(filename, '.');
if (parts.length >= 2) {
extension = _.last(parts);
}
return extension;
}
Для этого в модуле path есть стандартная библиотечная функция:
import path from 'path';
console.info(path.extname('abc.txt'));
Выход:
.txt
Итак, если вам нужен только формат:
path.extname('abc.txt').slice(1) // 'txt'
Если расширения нет, функция вернет пустую строку:
path.extname('abc') // ''
Если вы используете Node, то path является встроенным. Если вы ориентируетесь на браузер, тогда Webpack объединит для вас реализацию path. Если вы настраиваете браузер без Webpack, вы можете включить просмотр пути вручную.
Нет причин делать разбиение строк или регулярное выражение.
Кто что сказал про узел?
Ваш аргумент в пользу отказа от разделения или регулярных выражений - включить плагин или связать приложение с узлом, это лучший ответ для черной задачи.
@ShannonHochkins большую часть времени вы все равно настраиваете эти вещи
@AndreiDraganescu Я не собирался быть снисходительным, поэтому смягчил его.
"однострочный" для получения имени файла и расширения с использованием 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.info({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.info({filename, extension});
// {
// "filename": "filename.with_dot",
// "extension": "png"
// }
Вы можете использовать babel / typescript / polyfills для отсутствия функций ES7 + в IE 11
// 获取文件后缀名
function getFileExtension(file) {
var regexp = /\.([0-9a-z]+)(?:[\?#]|$)/i;
var extension = file.match(regexp);
return extension && extension[1];
}
console.info(getFileExtension("https://www.example.com:8080/path/name/foo"));
console.info(getFileExtension("https://www.example.com:8080/path/name/foo.BAR"));
console.info(getFileExtension("https://www.example.com:8080/path/name/.quz/foo.bar?key=value#fragment"));
console.info(getFileExtension("https://www.example.com:8080/path/name/.quz.bar?key=value#fragment"));Я знаю, что это старый вопрос, но я написал эту функцию с тестами для извлечения расширения файла, и она доступна с NPM, Yarn, Bit.
Может кому поможет.
https://bit.dev/joshk/jotils/get-file-extension
function getFileExtension(path: string): string {
var regexp = /\.([0-9a-z]+)(?:[\?#]|$)/i
var extension = path.match(regexp)
return extension && extension[1]
}
Вы можете увидеть тесты, которые я написал здесь.
Простой способ получить имя файла даже с несколькими точками в имени
var filename = "my.filehere.txt";
file_name = filename.replace('.'+filename.split('.').pop(),'');
console.info("Filename =>"+file_name);
OutPut: my.filehere
extension = filename.split('.').pop();
console.info("Extension =>"+extension);
Вывод: txt
Попробуйте это однострочный код
Также существует простой подход с использованием деструктуризации ES6:
const path = 'hello.world.txt'
const [extension, ...nameParts] = path.split('.').reverse();
console.info('extension:', extension);
Он работает отлично, но вы упустили, что вам придется удалить все остальное содержимое строки: return filename.replace (/^.*? \. ([A-zA-Z0-9] +) $ /, «$ 1»);