Js получить расширение файла
Более новое Редактирование: Много вещей изменилось, так как этот вопрос был первоначально отправлен - в пересмотренном ответе Уоллесера есть много действительно хорошей информации , а также отличная разбивка VisioN
Редактировать: только потому, что это принятый ответ; Ответ Уоллесера действительно намного лучше:
Мой старый ответ:
Должен сделать это.
Изменить: В ответ на комментарий PhiLho, используйте что-то вроде:
Все возможные случаи обрабатываются следующим образом: return filename.split ("."). Slice (1) .pop () || "";
@JustAndrei Еще не все :) Для чистого имени файла (базовое имя?), А не для пути, по практическим соображениям, я думаю, что это должно быть. return filename.substring(0,1) === '.' ? '' : filename.split('.').slice(1).pop() || ''; Это также заботится о .file (Unix скрытых, я считаю) видах файлов. То есть, если вы хотите сохранить его как одну строчку, на мой вкус, это немного грязно.
Редактировать:
Это еще одно решение без регулярных выражений, которое я считаю более эффективным:
Есть некоторые угловые случаи, которые лучше обрабатываются ответом VisioN ниже, особенно файлы без расширения (и .htaccess т. Д. Включены ).
Он очень производительный и обрабатывает угловые случаи, возможно, лучшим способом, возвращая "" вместо полной строки, когда нет точки или нет строки перед точкой. Это очень хорошо продуманное решение, хотя и сложное для чтения. Вставьте его в свою библиотеку помощников и просто используйте его.
Более безопасная реализация, если вы собираетесь запускать файлы без расширения или скрытые файлы без расширения (см. Комментарий VisioN к ответу Тома выше), будет что-то вроде этого
Если a.length это один, это видимый файл без расширения, т.е. файл
Если a[0] === "" и a.length === 2 это скрытый файл без расширения т.е. .htaccess
Надеюсь, что это поможет прояснить проблемы с немного более сложными случаями. С точки зрения производительности, я считаю, что это решение немного медленнее, чем регулярные выражения в большинстве браузеров. Тем не менее, для наиболее распространенных целей этот код должен быть полностью применим.
Новые Изменения: многое изменилось с тех пор, как этот вопрос был первоначально опубликован - есть много действительно хорошей информации в пересмотренный ответ wallacer а также отличное разрушение зрения
Edit: только потому, что это принятый ответ;wallacer это действительно намного лучше:
мой старый ответ:
должны сделать он.
Edit: в ответ на комментарий PhiLho, использовать что-то вроде:
сохранить его простым :)
Edit:
это еще одно решение без регулярных выражений, которое я считаю более эффективным:
есть некоторые случаи, которые лучше обрабатываются видение ниже, особенно файлы без расширений ( .htaccess и т. д.).
это очень эффективно, и обрабатывает угловые случаи, возможно, лучше, возвращая "" вместо полной строки, когда перед точкой нет ни точки, ни строки. Это очень хорошо продуманное решение, хотя и трудно читать. Вставьте его в своих помощниках lib и просто используйте его.
Старый Редактирование:
более безопасная реализация, если вы собираетесь запускать файлы без расширения или скрытые файлы без расширения (см. комментарий VisioN к ответу Тома выше), будет чем-то вроде этих строк
если a.length один, это видимый файл без расширения ie.
если a[0] === "" и a.length === 2 это скрытый файл без расширения ie. .реврайт
надеюсь, что это поможет прояснить проблемы с немного более сложными случаями. С точки зрения производительности, я считаю, что это решение немного медленнее, чем regex в большинстве браузеров. Тем не менее, для большинства распространенных целей этот код должен быть отлично использован.
следующее решение:быстро и short достаточно использовать в массовых операциях и сохранять дополнительные байты:
вот еще одно однострочное универсальное решение без регулярного выражения:
оба работают правильно с именами, не имеющими расширения (например,myfile) или начиная с . точка (например,.реврайт):
если вы заботитесь о скорости запуска benchmark и проверьте, что предоставленные решения являются самыми быстрыми, в то время как короткий чрезвычайно быстрый:
как работает короткий:
- String.lastIndexOf метод возвращает последнюю позицию подстроки (т. е. "." ) в данной строке (т. е. fname ). Если подстрока не найдена, метод возвращает -1 .
- "неприемлемой" позицию точка в имени файла -1 и 0 , которые соответственно ссылаются на имена без расширения (например, "name" ) и к именам, которые начинаются с точки (например, ".htaccess" ).
- оператор сдвига вправо с нулевым заполнением ( >>> ) при использовании с нулем влияет на преобразование отрицательных чисел -1 to 4294967295 и -2 to 4294967294 , что полезно для сохранения имени файла без изменений в крайних случаях (своего рода трюк здесь).
- String.prototype.slice извлекает часть имени файла из позиции, которая была вычислена, как описано. Если номер позиции больше длины строки, метод возвращает "" .
если вы хотите более четкое решение, которое будет работать таким же образом (плюс с дополнительной поддержкой полного пути), проверьте следующую расширенную версию. Это решение будет медленнее чем предыдущие ОДН-вкладыши но гораздо легке для того чтобы понять.
все три варианты должны работать в любом веб-браузере на стороне клиента и могут использоваться в коде NodeJS на стороне сервера.
код
тест
обратите внимание, что при отсутствии запроса фрагмент все еще может присутствовать.
JSLint
быстрый и работает правильно с путями
в некоторых случаях
решения с использованием split медленны, а решения с lastIndexOf не обрабатывают крайние случаи.
Я просто хотел поделиться этой.
хотя это имеет падение, что файлы без расширения вернут последнюю строку. но если вы это сделаете, это исправит все:
edit: странно (или, может быть, это не так) во втором аргументе метода replace не работает. Извиняюсь.
Я только что понял, что недостаточно прокомментировать ответ p4bl0, хотя ответ Тома явно решает проблему:
для большинства приложений, простой скрипт, например
будет работать просто отлично (как предусмотрено Томом). Однако это не доказательство глупости. Он не работает, если указано следующее имя файла:
это может быть немного перебор, но я бы предложил использовать синтаксический анализатор url, такой как этот чтобы избежать сбоя из-за непредсказуемых имен файлов.
используя эту конкретную функцию, вы можете получить имя файла, например это:
это выведет " изображение.jpg " без url vars. Тогда вы можете захватить расширение файла.
всегда возвращает расширение lower cas, чтобы вы могли проверить его при изменении поля работает на:
.В формате JPEG (без расширения) . (noextension)
Если вы ищете конкретное расширение и знаете его длину, вы можете использовать substr:
Я много лун опоздал на вечеринку, но для простоты я использую что-то вроде этого
однострочное решение, которое также будет учитывать параметры запроса и любые символы в url.
ответ Wallacer хорош, но необходима еще одна проверка.
Если файл не имеет расширения, он будет использовать filename как расширение, которое не является хорошим.
Не забывайте, что некоторые файлы не имеют расширения, так:
не быть самоуверенным, или дуть в свою трубу, но я не видел любой блок кода для этой задачи (поиск 'правильный' расширение файла, среди батареи различных function входные аргументы), который работает так же, как и это.
строку: fileNameOrURL(само собой разумеется)
Boolean: showUnixDotFiles (показывать или нет файлы, начинающиеся с точки ".")
примечание (2): Если вам нравится мой код, обязательно добавьте его в свою библиотеку js и/или РЕПО, потому что я много работал над его совершенствованием, и было бы стыдно тратить впустую. Итак, без дальнейших церемоний, вот это:
Edit: Just because this is the accepted answer; wallacer's answer is indeed much better:
Edit: In response to PhiLho's comment, use something like:
@JustAndrei Still not all :) For pure file name (basename?), not a path, for practical reasons, I think it should be return filename.substring(0,1) === '.' ? '' : filename.split('.').slice(1).pop() || ''; This takes care of .file (Unix hidden, I believe) kind of files too. That is if you want to keep it as a one-liner, which is a bit messy to my taste.
Edit:
This is another non-regex solution that I think is more efficient:
There are some corner cases that are better handled by VisioN's answer below, particularly files with no extension ( .htaccess etc included).
It's very performant, and handles corner cases in an arguably better way by returning "" instead of the full string when there's no dot or no string before the dot. It's a very well crafted solution, albeit tough to read. Stick it in your helpers lib and just use it.
Old Edit:
A safer implementation if you're going to run into files with no extension, or hidden files with no extension (see VisioN's comment to Tom's answer above) would be something along these lines
If a.length is one, it's a visible file with no extension ie. file
If a[0] === "" and a.length === 2 it's a hidden file with no extension ie. .htaccess
This should clear up issues with the slightly more complex cases. In terms of performance, I think this solution is a little slower than regex in most browsers. However, for most common purposes this code should be perfectly usable.
but in this case the file name looks like filname.tes.test.jpg. Kindly consider the output. I hope it will be false.
Brilliant! Thanks very much. It's nice to see a solution not using regex; I have done this with PHP and it only uses a couple of functions. +1
@wallacer: What happens if filename actually doesn't have an extension? Wouldn't this simply return the base filename, which would be kinda bad?
The following solution is fast and short enough to use in bulk operations and save extra bytes:
Here is another one-line non-regexp universal solution:
Both work correctly with names having no extension (e.g. myfile) or starting with . dot (e.g. .htaccess):
If you care about the speed you may run the benchmark and check that the provided solutions are the fastest, while the short one is tremendously fast:
How the short one works:
-
method returns the last position of the substring (i.e. "." ) in the given string (i.e. fname ). If the substring is not found method returns -1 .
- The "unacceptable" positions of dot in the filename are -1 and 0 , which respectively refer to names with no extension (e.g. "name" ) and to names that start with dot (e.g. ".htaccess" ). ( >>> ) if used with zero affects negative numbers transforming -1 to 4294967295 and -2 to 4294967294 , which is useful for remaining the filename unchanged in the edge cases (sort of a trick here). extracts the part of the filename from the position that was calculated as described. If the position number is more than the length of the string method returns "" .
If you want more clear solution which will work in the same way (plus with extra support of full path), check the following extended version. This solution will be slower than previous one-liners but is much easier to understand.
All three variants should work in any web browser on the client side and can be used in the server side NodeJS code as well.
@mrbrdo This method is not supposed to work with full path only with filenames, as requested by the question. Read question carefully before downvoting.
Why go to lengths to optimize such a trivial line of code? Tilde and bitshift operators are so seldom seen in JavaScript that I cannot support such an answer. If it takes 5 bullet points to explain how 1 line of code works, better to rewrite the code so it is actually understandable.
The speed of this one line will make no perceptible difference in any application. Bitwise is so seldom used that popular linters like JSLint and JSHint warn against using them. Obsessing over the performance and compactness of this logic has degraded the quality of the code; if code requires "extra investigation," I consider it "bad."
@Jackson Considering this is a site for offering multiple solutions to a problem, having a solution which optimizes performance is never a bad thing. You're statement "will make no perceptible difference in any application" is completely based on your narrow scope of possible applications this could be used in. Beyond that, it may provide someone looking at the problem a learning experience in which they can optimize some other code they need to make for a computing intensive application they are writing.
There is a standard library function for this in the path module:
So, if you only want the format:
If there is no extension, then the function will return an empty string:
If you are using Node, then path is built-in. If you are targetting the browser, then Webpack will bundle a path implementation for you. If you are targetting the browser without Webpack, then you can include path-browserify manually.
There is no reason to do string splitting or regex.
Your argument for not using splitting or regular expressions is to include plugin or bundle the application with node, it's an over the top answer for a menial task
Works well. webpack is very commonly already in place with client side development targeting browsers. This got established years ago. A server side developer working with node already has this built-in. Why duplicate the work already done for you? I would not use webpack just for this but if you have it use it.
If you are dealing with web urls, you can use:
This would result in a wrong extension captured when files are named something like: "2021.06.28 - MyReport.csv"
Code
Test
Notice that in the absence of a query, the fragment might still be present.
JSLint
Doesn't work if you have another slash introduced at the end like something encoded, i.e. this: "example.com:8080/segment1/segment2/page.html?enc=abc/def"
Fast and works correctly with paths
Some edge cases
Solutions using split are slow and solutions with lastIndexOf don't handle edge cases.
I've already listed the edge cases. And your solution does NOT handle them properly. Like I've already written, try "/dir.with.dot/file". Your code returns "dot/file" which is ridiculously wrong.
Like I already told you, that was never explicitly said, and a solution which handles paths is obviously much more useful. The answer to a question on SO is supposed to be useful to other people besides the person who asked the question. I really don't think a solution that handles a superset of inputs should be downvoted.
The downvote was for using global variable with .exec() . Your code will be better as (filename.match(/[^\\/]\.([^\\/.]+)$/) || [null]).pop() .
i just wanted to share this.
although this has a downfall that files with no extension will return last string. but if you do so this will fix every thing :
As far as I remember slice method refers to arrays rather than to strings. For strings substr or substring will work.
@VisioN but i guess you should know that there is String.prototype.slice and also a Array.prototype.slice so it kinda both work ways kinda of method
"one-liner" to get filename and extension using reduce and array destructuring :
with better indentation :
Not to be overconfident, or blowing my own trumpet, but I haven't seen any block of code for this task (finding the 'correct' file extension, amidst a battery of different function input arguments) that works as well as this does.
Note: By design, if a file extension doesn't exist for the given input string, it simply returns a blank string "" , not an error, nor an error message.
String: fileNameOrURL(self-explanatory)
Boolean: showUnixDotFiles (Whether or Not to show files that begin with a dot ".")
Note (2): If you like my code, be sure to add it to your js library's, and/or repo's, because I worked hard on perfecting it, and it would be a shame to go to waste. So, without further ado, here it is:
Я создаю функцию загрузки файла в node.js с экспресс-3.
Я хотел бы получить расширение файла изображения. так что я могу переименовать файл, а затем добавить расширение файла к нему.
Как я могу получить расширение изображения в node.js?
Я считаю, что вы можете сделать следующее, чтобы получить расширение имени файла.
Только будьте осторожны, он будет захватывать только символы после последней точки, поэтому имена файлов вроде app.css.gz будут только возвращаться, .gz а не возвращаться .css.gz , что может или не может быть тем, что вы хотите.
Как правило, расширение является последним. И когда мы ожидаем более одного, например, tar.gz. лучше проверить, существует ли он в конце концов или нет. используя регулярное выражение, например. "tar.gz $" или созданием функции, которая делает это. как проверить это с конца и вернуться назад и посмотреть, полностью ли это соответствует. и у вас будет эта функция, которая проверяет расширение. ЗАЧЕМ? потому что насчет файлов, таких как jone.lastTest.654654556.tar.gz здесь, ожидаемое расширение - tar.gz, но если вы примените какую-либо функцию, которая дает форму 1-й точки, она не будет работать, как вы можете видеть
Обновить
Поскольку оригинальный ответ, extname () был добавлен в path модуль, см. Ответ Snowfish.
Оригинальный ответ:
Я использую эту функцию, чтобы получить расширение файла, потому что я не нашел способ сделать это более простым способом (но я думаю, что есть):
Вы должны требовать «путь», чтобы использовать его.
другой метод, который не использует модуль пути:
Да, это работает. Просто подумал, что будет проще использовать узел. Это то, что я сделал: var is = fs.createReadStream(req.files.upload.path), fileType = is.path.split(/[. ]+/).pop();
Если вы используете экспресс, добавьте следующую строку при настройке промежуточного программного обеспечения (bodyParser)
Гораздо эффективнее использовать substr() метод вместо split() & pop()
Обновление август 2019 г. Как отметил @xentek в комментариях; substr() теперь считается устаревшей функцией ( документация MDN ). Вы можете использовать substring() вместо этого. Разница между substr() и substring() заключается в том, что второй аргумент substr() - это максимальная длина для возврата, в то время как второй аргумент substring() - это индекс, на котором нужно остановиться (без включения этого символа). Кроме того, substr() принимает отрицательные начальные позиции, которые будут использоваться в качестве смещения от конца строки, в то время substring() как нет.
Теперь есть предупреждение, поскольку substr оно считается устаревшей функцией, и ее следует избегать, когда это возможно. Дополнительная информация по MDN
Это решение поддерживает строки запросов!
Простое решение без необходимости в требовании, которое решает проблему многократного продления периода:
Или, если вы не хотите, чтобы начальная точка:
Убедитесь, что у файла тоже есть расширение.
Я думаю, что отображение заголовка Content-Type в запросе также будет работать. Это будет работать даже в тех случаях, когда вы загружаете файл без расширения. (когда имя файла не имеет расширения в запросе)
Здесь name Content-Type header содержит тип mime данных. Отображение этого типа MIME на расширение даст вам расширение файла :).
Restify BodyParser преобразует этот заголовок в свойство с типом имени
Вы можете использовать этот заголовок и выполнять сопоставление расширений (подстроку и т. Д.) Вручную, но для этого также есть готовые библиотеки. Ниже двух были лучшие результаты, когда я делал поиск Google
Выше методы описаны ниже один за другим с соответствующим примером.
Полное имя файла сначала получается путем выбора файла ввода и получения его значения свойства. Это возвращает имя файла в виде строки.
С помощью метода split () мы разделим имя файла на 2 части. Первая часть будет именем файла, а вторая часть будет расширением файла.
Расширение может быть получено путем извлечения из массива последней строки методом pop (). Следовательно, это расширение файла выбранного файла.
Синтаксис:
Пример:
< title >How to get file extensions using JavaScript? title >
< b >Here we will get "Extension" of selected file b >
< p >Select a file and click on the button
to check the file extension. p >
< p >The file extension is: p >
Выход:
Начальный индекс задается с помощью метода lastIndexOf (). Это возвращает индекс в строке, где встречается строка, переданная последним. Последний индекс можно найти, передав точку (.) Этому методу. Индекс передается методу substring (), который возвращает строку от точки (.) До конца. Это расширение файла.
Синтаксис:
Пример:
< title >How to get file extensions using JavaScript? title >
< b >Here we will get "Extension" of selected file b >
< p >Select a file and click on the button
to check the file extension. p >
< p >The file extension is: p >
extension = fileName.substring(fileName.lastIndexOf('.') + 1);
Выход:
Регулярные выражения могут быть использованы для извлечения расширения файла из полного имени файла. Новый объект RegExp создается с регулярным выражением «[^.] + $». Символ каретки (^) отмечает начало строки. Точка (.) После каретки указывает, что строка выбрана после точки. Квантор плюс (+) выбирает одно или несколько слов. Доллар ($) используется для указания конца строки. Это выражение выбирает строку после точки.
Метод match () используется для возврата части строки, которая соответствует регулярному выражению, переданному ему в качестве параметра. Полное имя файла передается этому методу, а регулярное выражение возвращает только расширение файла.
Читайте также: