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

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

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

function getFileExtension(filename) {
    /*TODO*/
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
565
0
594 941
36
Перейти к ответу Данный вопрос помечен как решенный

Ответы 36

return filename.replace(/\.([a-zA-Z0-9]+)$/, "");

edit: Странно (или, может быть, это не так), во втором аргументе метода замены, похоже, не работает ... Извините.

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

roenving 10.10.2008 18:03
Ответ принят как подходящий

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


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

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

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

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

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

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

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

Разве не дорого выполнять регулярное выражение дважды?

Andrew Hedges 11.10.2008 11:39

лучше использовать регулярное выражение, чем lastindexof? благодаря.

melaos 07.01.2009 11:31

Высоко оцененный ответ ниже намного лучше.

fletom 13.02.2012 21:08

К сожалению, оба решения не подходят для таких имен, как файл и .htaccess.

VisioN 15.10.2012 21:19

regexp, вероятно, быстрее, чем разбиение на массив, чтобы получить последнее значение

mrbrdo 30.09.2013 08:30

Все возможные случаи обрабатываются следующим образом: return filename.split ("."). Slice (1) .pop () || "";

JustAndrei 10.04.2014 16:59

@JustAndrei Еще не все :) Для чистого имени файла (базового имени?), А не пути, по практическим соображениям, я думаю, что это должно быть return filename.substring(0,1) === '.' ? '' : filename.split('.').slice(1).pop() || '';. Это также касается файлов типа .file (Unix, я считаю, скрытый). То есть, если вы хотите сохранить его как однострочник, что на мой вкус немного беспорядочно.

kooker 21.06.2014 08:00

С таким именем файла, как path / to / file.png? V1.4.1, это не сработает!

dude 01.09.2015 10:04

Добавлен еще один ответ, который будет учитывать параметры запроса: stackoverflow.com/a/35526475/1872133

Labithiotis 20.02.2016 20:22

Плохое решение. Как уже указали несколько пользователей, возвращает имя файла, если у него нет расширения.

JayC667 31.07.2018 16:13

Лучше просто использовать модуль pathstackoverflow.com/a/52738209/1256041

sdgfsdh 10.10.2018 13:37

Плюс один от меня, потому что вы упомянули лучший ответ

YaakovHatam 24.06.2020 10:47

есть небольшая проблема со сплитом. Если вы используете (по какой-либо причине) jquery, он станет медленным из-за того, что jquery пытается самостоятельно обработать split (). В этом случае ответы другого лайнера будут быстрее. Например. используйте один вкладыш без разделения.

Thomas Ludewig 28.01.2021 16:59

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 (шаблон);

spc16670 07.10.2016 21:35

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

pc1oad1etter 29.06.2010 08:17

но в этом случае имя файла выглядит как filename.teas.test.jpg. Пожалуйста, рассмотрите вывод. Надеюсь, это будет неправда.

Fero 02.07.2010 13:56

в этом случае вывод будет "jpg"

wallacer 29.09.2010 01:53

Блестяще! Огромное спасибо. Приятно видеть решение, не использующее регулярное выражение; Я сделал это с помощью PHP, и он использует только несколько функций. +1

Bojangles 01.12.2010 23:01

@wallacer: Что произойдет, если у filename на самом деле нет расширения? Разве это не вернет просто базовое имя файла, что было бы неплохо?

Nicol Bolas 27.10.2011 00:33

Можно подумать о том, чтобы добавить .toLowerCase () в конец.

MrBojangles 29.10.2011 04:09

@NicolBolas, да, будет. Это была самая простая реализация без регулярных выражений, о которой я мог подумать примерно за 5 секунд около 2 лет назад. Хотя, похоже, помогает людям :) Он определенно должен быть взбудоражен небольшой обработкой ошибок, более низким корпусом и т. д. Для реального использования.

wallacer 16.11.2011 04:38

Опечатка в разделе "Правка". Должен быть var a = filename.split(".");

GEMI 30.09.2013 14:21

не работает для "/home/user/.app/config" (даже с "улучшенной" версией).

mrbrdo 13.10.2013 19:47

@mrbrdo Правдивая история - я предполагаю, что filename.split ('/'). pop (). split ('.'). pop () будет обрабатывать абсолютные пути. Хороший улов! ;)

wallacer 17.10.2013 20:54

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

mrbrdo 18.10.2013 19:35

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

wallacer 19.10.2013 01:38

@wallacer К сожалению, ваше новейшее решение не работает с файлами, начинающимися с точки, например .htaccess и файлы, не имеющие вообще никакого расширения. Это была основная причина, по которой я использовал более сложную логику в своем ответе.

VisioN 03.06.2015 18:27

@VisioN Хорошо, спасибо, что указали на это! Я обновил свой ответ, рекомендуя ваше блестящее решение.

wallacer 03.06.2015 20:57

С таким именем файла, как path / to / file.png? V1.4.1, это не сработает!

dude 01.09.2015 10:05

@julmot, какое расширение вы ожидаете от этого файла? .png? Вы пытаетесь использовать строку запроса, потому что она больше похожа на file.png? V = 1.4.1. Если вы храните файлы с именами типа "file.png? V1.4.1" и ожидаете, что ваша файловая система будет обрабатывать их как файлы .png, у вас, мой друг, дела пойдут не так хорошо. Да, если у вас есть какой-то странный вариант использования, выходящий за рамки нормальности, тогда конечно, этот алгоритм не читает ваши мысли и не извлекает .png из середины строки. Совершенно ясно, что он делает. Если это не то, что вам нужно, используйте что-нибудь другое.

wallacer 02.09.2015 00:52

Если вы создаете новое имя файла и хотите извлечь расширение, чтобы прикрепить его к другому базовому имени, тогда полезно иметь расширение "." но только если расширение существует. Так что измените 2 на 1, и вы можете сделать newname = newbase + fname.substr ((~ -fname.lastIndexOf (".") >>> 0) + 1); Не нужно возиться с условным добавлением точки.

Julian Mann 11.02.2016 04:51

Ржу не могу. Как вы, ребята, можете найти такой ответ? Без расширения -> вы получаете имя файла ... плохо, плохо ...

JayC667 31.07.2018 16:15

Это не сработает для путей. Например 'http:://someurl.com/file.png?user_token=some.hash.with.dot'

Alvaro 27.07.2020 15:02

Для большинства приложений простой сценарий, например

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)? '': доб;

Michiel 15.11.2014 00:37

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"

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

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.info( getExtension("/path/to/file.ext") );
// >> "ext"

Все три варианта должны работать в любом веб-браузере на стороне клиента и могут также использоваться в коде NodeJS на стороне сервера.

@Zipp Для большей понятности я добавил описание подхода и сравнение скорости, чтобы проиллюстрировать, насколько быстро решение.

VisioN 08.10.2013 19:34

"fname.substr ((~ -fname.lastIndexOf (". ") >>> 0) + 2)" дает неверное значение для ".htaccess".

Benny Neugebauer 09.10.2013 14:35

@BennyNeugebauer Что не так в вашем случае? Он дает "", поскольку имя файла, начинающееся с точки (например, .htaccess или .htpasswd), не имеет расширения.

VisioN 09.10.2013 14:45

Я ожидал, что расширение будет "htaccess"? Но это вопрос мнения. Ты прав! Я просто хотел указать. :)

Benny Neugebauer 09.10.2013 14:49

@BennyNeugebauer Технически .htaccess не имеет расширения, так как это является само расширение. Этому соглашению придерживаются многие библиотеки и языки программирования. Например, в Python, когда вы выполняете os.path.splitext('/path/to/.htaccess'), он возвращает "" как расширение игнорирование ведущей точки, учитывая такое имя как имя файла без расширения.

VisioN 09.10.2013 15:10

@BennyNeugebauer Однако, если вам нужно исключить это правило, просто используйте вместо него fname.substr((fname.lastIndexOf(".") >>> 0) + 1) :)

VisioN 09.10.2013 15:15

Не работает. "/home/user/.app/config" возвращает "app / config", что совершенно неверно.

mrbrdo 13.10.2013 19:45

@mrbrdo Этот метод не должен работать с полным путем только с именами файлов, как того требует вопрос. Внимательно прочтите вопрос, прежде чем голосовать против.

VisioN 13.10.2013 19:55

он никогда не говорил об этом прямо, и очевидно, что это делает его более полезным, если он работает на путях

mrbrdo 18.10.2013 19:29

@Ajit, вероятно, потому что это решение намного более новое, чем те, что вверху ... Это вопрос 5-летней давности, а этому решению всего год ... И да. Это хорошее решение

wallacer 19.10.2013 01:46

Зачем так стараться оптимизировать такую ​​тривиальную строку кода? Операторы тильды и битового сдвига настолько редко встречаются в JavaScript, что я не могу поддержать такой ответ. Если для объяснения того, как работает 1 строка кода, требуется 5 пунктов, лучше переписать код, чтобы он был действительно понятным.

Jackson 08.07.2015 07:46

@Jackson 1) Если вы не видите и не используете операторы тильды и битового сдвига в своем коде JavaScript, у меня для вас плохие новости. 2) Если вы всегда принимаете и используете код, который вам понятен, без дополнительных исследований, то у меня также для вас плохие новости. Если вы не понимаете сложный код, это не всегда означает, что код плохой. В текущем примере более чем ясно, что этот фрагмент кода работает во много раз быстрее, чем любые другие альтернативы, что делает его идеальным для использования в массовых операциях. Также важно сделать его компактным. И есть описание для людей, которые хотят учиться.

VisioN 08.07.2015 10:55

Скорость этой одной строки не будет иметь заметного значения для любого приложения. Побитовое использование настолько редко, что популярные линтеры, такие как JSLint и JSHint, предостерегают от их использования. Одержимость производительностью и компактностью этой логики ухудшила качество кода; если код требует «дополнительного исследования», я считаю его «плохим».

Jackson 08.07.2015 22:11

@VisioN Общая проблема здесь в том, что у простой задачи должно быть простое решение. В противном случае трудно сказать, есть ли небольшие ошибки. Если вы требуете, чтобы другие читали ваш код несколько раз, прежде чем они смогут понять, почему он работает, и ваш код полон этого, никто (даже вы) не сможет обнаружить ошибки на раннем этапе. После этого ваша команда будет обречена на поиски ошибок. Без всякой выгоды. Тесты отвлекают, они просто показывают, что эта оптимизация не стоит проблем, поскольку очевидное решение уже работает на порядки быстрее, чем необходимо.

vog 22.08.2015 15:25

@vog Если вам не нравится код или вы считаете его бесполезным, вы можете использовать другой или реализовать собственное более простое решение, которое будет правильно работать с разными входными данными. Я лично считаю это решение работоспособным и полезным для моих нужд. Более того, я не вижу проблем в чтении описания того, как это работает, или просто игнорирую его, если вы не утруждаетесь его пониманием. Использовать это или нет - ваше решение, я просто поделился тем, что некоторые могут найти полезными.

VisioN 22.08.2015 15:52

@VisioN Я знаю, что могу не любить этот код, поэтому могу просто проигнорировать его. Но поскольку это часть публичного ответа на общественный вопрос, я почувствовал побуждение объяснить, что именно мне в нем не нравится.

vog 26.08.2015 20:29

А как насчет двойных удлинителей, например .tar.gz?

Slava 21.02.2016 00:22

@ Alph.Dev Я сомневаюсь, что вы сможете найти какой-либо действующий алгоритм для различения всех типов расширений, не имея какой-либо базы данных для проверки. Кроме того, насколько я понимаю, .tar.gz не является расширением, поскольку расширение .gz для GZIP-файла с расширением .tar, который является архивом TAR.

VisioN 21.02.2016 03:57

@Jackson Учитывая, что это сайт, предлагающий несколько решений проблемы, наличие решения, которое оптимизирует производительность, никогда не бывает плохим. Ваше заявление «не будет иметь заметных различий ни в одном приложении» полностью основано на вашем узком диапазоне возможных приложений, в которых это может быть использовано. Помимо этого, оно может дать тем, кто занимается проблемой, опыт обучения, в котором они могут оптимизировать некоторые другой код, который им нужно сделать для написанного ими приложения с интенсивными вычислениями.

nrylee 27.06.2017 22:01

Я думаю, что str.length также будет работать вместо Infinity. хороший ответ кстати

Ahmad 22.09.2020 13:14

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

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

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

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. Он отлично работает во всех случаях и намного быстрее, чем любое регулярное выражение.

VisioN 06.10.2013 12:17

Я уже перечислил крайние случаи. И ваше решение НЕ обрабатывает их должным образом. Как я уже писал, попробуйте "/dir.with.dot/file". Ваш код возвращает «точку / файл», что до смешного неверно.

mrbrdo 13.10.2013 19:41

Никто не просил разбирать путь. Вопрос был в извлечении расширений из имен файлов.

VisioN 13.10.2013 19:59

Как я уже сказал вам, об этом никогда не говорилось явно, и решение, которое обрабатывает пути, очевидно, намного полезнее. Предполагается, что ответ на вопрос о SO будет полезен другим людям, помимо человека, задавшего вопрос. Я действительно не думаю, что решение, которое обрабатывает расширенный набор входных данных, должно быть отвергнуто.

mrbrdo 18.10.2013 19:32

Голос против был за использование глобальной переменной с .exec(). Ваш код будет лучше как (filename.match(/[^/]\.([^/.]+)$/) || [null]).pop().

VisioN 18.10.2013 20:15

Значит, вы могли бы так сказать. Глобальная переменная ускользнула от меня, так как я использую это в Coffeescript, моя проблема в этом.

mrbrdo 18.10.2013 22:22

я просто хотел поделиться этим.

fileName.slice(fileName.lastIndexOf('.'))

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

   function getExtention(fileName){
     var i = fileName.lastIndexOf('.');
     if (i === -1 ) return false;
     return fileName.slice(i)
   }

Насколько я помню, метод slice относится к массивам, а не к строкам. Для струн substr или substring подойдет.

VisioN 06.10.2013 12:20

@VisioN, но я думаю, вы должны знать, что есть String.prototype.slice, а также Array.prototype.slice, так что это как бы оба способа работы своего рода метод

Hussein Nazzal 06.10.2013 16:35

О да. Ты прав. Совершенно забыл об этом методе. Виноват.

VisioN 06.10.2013 17:26

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 14.09.2014 04:07

@asiby Подобные решения являются основной причиной падения космических ракет после запуска.

VisioN 12.01.2015 20:44

Я опаздываю на вечеринку на много лун, но для простоты использую что-то вроде этого

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
(1) If a file has no extension, this will still return the file name. (2) If there is a fragment in the URL, but no query (e.g. page.html#fragment), this will return the file extension and the fragment.
Jack 10.07.2016 04:03

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"

Jester 04.12.2020 21:58

Это простое решение

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

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

Потрясающий. Спасибо!

GollyJer 08.06.2018 07:08

Если вы имеете дело с веб-адресами, вы можете использовать:

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/

Мне очень нравится ваше решение. Он так много делает с таким малым. Я собираюсь использовать это.

Jules Manson 30.01.2018 03:08

fetchFileExtention(fileName) {
    return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2);
}

Хотя этот фрагмент кода может решить вопрос, включая объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причины вашего предложения кода.

Brett DeWoody 27.03.2018 11:54

Я предпочитаю использовать 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, вы можете включить просмотр пути вручную.

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

Кто что сказал про узел?

Shannon Hochkins 11.04.2019 08:22

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

Shannon Hochkins 12.04.2019 08:47

@ShannonHochkins большую часть времени вы все равно настраиваете эти вещи

sdgfsdh 26.09.2019 19:43

@AndreiDraganescu Я не собирался быть снисходительным, поэтому смягчил его.

sdgfsdh 14.01.2020 02:07

"однострочный" для получения имени файла и расширения с использованием 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

boehm_s 22.04.2020 20:22

// 获取文件后缀名
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);

Другие вопросы по теме