Обрезать расширение файла js
Новые Изменения: многое изменилось с тех пор, как этот вопрос был первоначально опубликован - есть много действительно хорошей информации в пересмотренный ответ 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 и/или РЕПО, потому что я много работал над его совершенствованием, и было бы стыдно тратить впустую. Итак, без дальнейших церемоний, вот это:
For example, assuming that x = filename.jpg , I want to get filename , where filename could be any file name (Let's assume the file name only contains [a-zA-Z0-9-_] to simplify.).
I saw x.substring(0, x.indexOf('.jpg')) on DZone Snippets, but wouldn't x.substring(0, x.length-4) perform better? Because, length is a property and doesn't do character checking whereas indexOf() is a function and does character checking.
Notes:
- The first one is a little bit slower cause performes more operations; but works in both cases, in other words it can extract the file name without extension from a given string that contains a path or a file name with ex. While the second works only if the given variable contains a filename with ext like filename.ext but is a little bit quicker.
- Both solutions work for both local and server files;
But I can't say nothing about neither performances comparison with other answers nor for browser or OS compatibility.
What's the most efficient way to trim the suffix in Java, like this:
He wasn't asking how to do it, he was asking what's the most efficient way. I came here looking for the same thing.
Примечания:
- первый немного медленнее, потому что выполняет больше операций, но работает в обоих случаях, другими словами он может извлечь имя файла без расширения из заданной строки, содержащей путь или имя файла с ex. В то время как второй работает только в том случае, если данная переменная содержит имя файла с ext like filename.ext но немного быстрее.
- оба решения работают как для локальных, так и для серверных файлов;
но я ничего не могу сказать ни о сравнении производительности с другими ответами, ни о совместимости браузера или ОС.
рабочий фрагмент 1: полный путь
рабочий фрагмент 2: имя файла с расширением
рабочий фрагмент 2: имя файла в двойные расширение
хотя уже довольно поздно, я добавлю другой подход, чтобы получить имя файла без расширения, используя простой старый JS -
здесь пригодятся регулярные выражения! Javascript .replace() метод примет регулярное выражение, и вы можете использовать его для выполнения того, что хотите:
еще один лайнер-мы предполагаем, что наш файл представляет собой jpg-изображение > > ex: var yourStr = 'test.jpg';
Например, предполагая, что x = filename.jpg , я хочу получить filename , где filename может быть любым именем файла (Предположим, что имя файла содержит только [a-zA-Z0-9-_ ] чтобы упростить.).
Я видел x.substring(0, x.indexOf('.jpg')) на DZone Snippets, но не смог > выступать лучше? Потому что length является свойством и не выполняет проверку символов, тогда как indexOf() является функцией и выполняет проверку символов.
Примечания:
- Первый немного медленнее, потому что выполняет больше операций; но работает в обоих случаях, другими словами, он может извлечь имя файла без расширения из заданной строки, содержащей путь или имя файла с помощью ex. В то время как второй работает, только если данная переменная содержит имя файла с ext, например filename.ext, но немного быстрее.
- Оба решения работают как с локальными, так и с серверными файлами;
Но я не могу ничего сказать ни о сравнении производительности с другими ответами, ни о совместимости браузера или ОС.
22 Answers 22
This is the sort of code that we shouldn't be doing ourselves. Use libraries for the mundane stuff, save your brain for the hard stuff.
For 95% of the projects, this should be the accepted answer. Rewriting code like this is the root cause for many headaches!
If you have Apache Commons I/O already in your project, that's right. But if this all you need from it, you're adding (at least) 2.5 MB of dead weight to your project for something that can be easily done with a single line.
if(str != null && str.contains(".")) str.substring(0, str.lastIndexOf('.')). FilenameUtils is another dependency, and not always available
As using the String.substring and String.lastIndex in a one-liner is good, there are some issues in terms of being able to cope with certain file paths.
Take for example the following path:
Using the one-liner will result in:
The result should have been c , but since the file lacked an extension, but the path had a directory with a . in the name, the one-liner method was tricked into giving part of the path as the filename, which is not correct.
Need for checks
In order to recreate its behavior, I wrote a few tests the new method should fulfill, which are the following:
(And that's all I've checked for -- there probably are other checks that should be in place that I've overlooked.)
The implementation
The following is my implementation for the removeExtension method:
Running this removeExtension method with the above tests yield the results listed above.
The method was tested with the following code. As this was run on Windows, the path separator is a \ which must be escaped with a \ when used as part of a String literal.
The results are the desired results outlined in the test the method should fulfill.
например, предполагая, что x = filename.jpg , Я хочу filename , где filename может быть любое имя файла (предположим, что имя файла содержит только [a-zA-Z0-9-_] для упрощения.).
Я видел x.substring(0, x.indexOf('.jpg')) on DZone Фрагменты, а не x.substring(0, x.length-4) лучше? Так, length - это свойство, а не характер проверки, а indexOf() - это функция, а не персонаж.
Если вы знаете длину расширения, вы можете использовать x.slice(0, -4) (где 4-Три символа расширения и точка).
Если вы не знаете длину @John hartsock regex будет правильным подходом.
Если вы не хотите использовать регулярные выражения, вы можете попробовать это (медленее):
обратите внимание, что он не будет работать с файлами без расширения.
не уверен, что будет работать быстрее, но это будет более надежным, когда дело доходит до расширения, как .jpg или .html
на узел.js, имя файла без расширения можно получить следующим образом.
дальнейшее объяснение в узел.js документация страница.
x.length-4 учитывает только расширения 3 символов. Что делать, если у вас есть filename.jpg или filename.pl ?
ответ. конечно, если у вас всегда есть продолжение .jpg , x.length-4 будет работать нормально.
однако, если вы не знаете длину вашего расширения, любое из нескольких решений лучше/надежнее.
x = x.substring(0, x.lastIndexOf('.'));
или (с предположением, что имя файла имеет только одну точку)
или (также только с одной точкой)
возможно, вы можете использовать предположение, что последняя точка будет разделителем расширения.
В Узел.версии js до 0.12.x:
конечно, это также работает в 0.12.х и позже.
это работает, даже если разделитель отсутствует в строке.
можно также использовать как ОДН-вкладыш как это:
EDIT: это более эффективное решение:
Мне нравится этот, потому что это один лайнер, который не слишком сложно прочитать:
вот еще одно решение на основе регулярных выражений:
Это должно отсечь только последний сегмент.
Я не знаю, является ли это допустимым вариантом, но я использую это:
Это не просто одна операция, которую я знаю, но, по крайней мере, он должен всегда работать!
принятый ответ удаляет только последнюю часть расширения ( .jpg ), что может быть хорошим выбором в большинстве случаев.
мне однажды пришлось лишить всех расширений ( .tar.gz ) и имена файлов были ограничены, чтобы не содержать точек (так 2015-01-01.backup.tar не было бы проблемой):
Если вам нужно обработать переменную, содержащую полный путь (например.: thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg" ) и вы хотите вернуть только "имя файла", которое вы можете использовать:
результат будет theName = = "filename";
чтобы попробовать, напишите следующую команду в окно консоли отладчика chrome: window.location.pathname.split("/").slice(-1).join().split(".").shift()
Если вам нужно обработать только имя файла и его расширение (ex.: theNameWithExt = "filename.jpg" ):
в результат будет theName = = "filename", то же, что и выше;
23 ответа
Если вы знаете длину расширения, вы можете использовать x.slice(0, -4) (где 4 - это три символа расширения и точка).
Если вы не знаете длину, регулярное выражение @John Hartsock было бы правильным подходом.
Если вы не хотите использовать регулярные выражения, вы можете попробовать это (менее производительно):
Обратите внимание, что это не удастся для файлов без расширения.
Еще один вкладыш:
Здесь регулярные выражения пригодятся! Метод .replace() Javascript будет принимать регулярное выражение, и вы можете использовать его для достижения желаемого:
Принятый ответ удаляет только последнюю часть расширения ( .jpg ), что может быть хорошим выбором в большинстве случаев.
Однажды мне пришлось удалить все расширения ( .tar.gz ), а имена файлов были ограничены, чтобы они не содержали точек (поэтому 2015-01-01.backup.tar не будет проблемой):
Вот еще одно решение на основе регулярных выражений:
Это должно только отрубить последний сегмент.
Вы можете использовать path для маневра.
x.length-4 учитывает только расширения из 3 символов. Что если у вас есть filename.jpg или filename.pl ?
Чтобы ответить . конечно, если у вас всегда есть расширение .jpg , x.length-4 будет работать нормально.
Однако, если вы не знаете длину своего расширения, любое из нескольких решений будет лучше / надежнее.
x = x.substring(0, x.lastIndexOf('.'));
ИЛИ (при условии, что имя файла имеет только одну точку)
ИЛИ (также только с одной точкой)
Это код, который я использую для удаления расширения из имени файла, без использования регулярных выражений или indexOf (indexOf не поддерживается в IE8). Предполагается, что расширением является любой текст после последнего '.' персонаж.
- файлы без расширения: "myletter"
- файлы с '.' в названии: "my.letter.txt"
- неизвестная длина расширения файла: "my.letter.html"
Это работает, даже если в строке нет разделителя.
Может также использоваться как однострочный:
РЕДАКТИРОВАТЬ: Это более эффективное решение:
Хотя уже довольно поздно, я добавлю другой подход, чтобы получить имя файла без расширения, используя старый добрый JS-
В node.js имя файла без расширения можно получить следующим образом.
Дальнейшие объяснения на странице документации Node.js .
Node.js удаляет расширение из каталога хранения полного пути
Также выводит каталог:
Протестировано в Node.js v10.15.2.
Если вам нужно обработать переменную, которая содержит полный путь (например, thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg" ), и вы хотите вернуть только «имя файла», вы можете использовать:
Результат будет theName == "filename" ;
Чтобы попробовать это, напишите следующую команду в окне консоли вашего отладчика Chrome: window.location.pathname.split("/").slice(-1).join().split(".").shift()
Если вам нужно обработать только имя файла и его расширение (например: theNameWithExt = "filename.jpg" ):
Результат будет theName == "filename" , такой же, как указано выше;
24 Answers 24
Not sure what would perform faster but this would be more reliable when it comes to extension like .jpg or .html
This works for any length of file extension (.txt or .html or .htaccess) and also allows for the file name to contain additional period (.) characters. It wouldn't handle eg .tar.gz due to the extension itself containing a period. It's more common for a file name to contain additional periods than a file extension. Thanks!
@Vik There's a difference between the 'right answer' and the accepted answer. An accepted answer is just the answer that was helpful for the one who asked the question.
I suppose that there may be issues with the Windows platform because there can be back slashes. So the regexp should be /\.[^/\\.]+$/.
In node.js, the name of the file without the extension can be obtained as follows.
Further explanation at Node.js documentation page.
This answer is pretty restricted to server-side node. If you try to use this in react code, it doesn't seem to import.
if you want to remove an extension from a path including the directories, you can do var parsed = path.parse(filename) followed by path.join(parsed.dir, parsed.name) .
If you know the length of the extension, you can use x.slice(0, -4) (where 4 is the three characters of the extension and the dot).
If you don't know the length @John Hartsock regex would be the right approach.
If you'd rather not use regular expressions, you can try this (less performant):
Note that it will fail on files without extension.
I like this solution the best. It's clean, and I can use it cause I know the file extension is always .jpg . I was looking for something like Ruby's x[0..-5] , and x.slice(0, -4) looks great! Thanks! And thank you to everyone else for all the other robust alternatives provided!
And if you're not 100% sure about the length of the extension, then don't this: "picture.jpg".slice(0, -4) -> "picture."
"If you know the length of the extension" It's been decades since this was an acceptable assumption to make. Don't use this anymore.
x.length-4 only accounts for extensions of 3 characters. What if you have filename.jpg or filename.pl ?
To answer. sure, if you always have an extension of .jpg , x.length-4 would work just fine.
However, if you don't know the length of your extension, any of a number of solutions are better/more robust.
x = x.substring(0, x.lastIndexOf('.'));
OR (with the assumption filename only has one dot)
OR (also with only one dot)
?? You can have a filename ex: "summer.family.jpg" in that case split('.')[0] will return only a partial file name. I would remove that one from the answer, or clearly state underneath the issue for that example. @basarat .
Something I do frequently regarding part splits: var parts = full_file.split("."); var ext = parts[parts.length-1]; var file = parts.splice(0,parts.length-1).join(".");
x.split(".") should not even be considered an answer. I know I use a '.' in almost all of my file naming conventions, i.e. 'survey.controller.js', or 'my.family.jpg'.
@Lee2808: Hence the warning of only one dot. This is simply meant to show that there are a number of approaches, depending on the application. I would certainly use one of the other methods in almost all cases.
You can perhaps use the assumption that the last dot will be the extension delimiter.
If file has no extension, it will return empty string. To fix that use this function
Shorter version that accounts for no dots. var f = x.substr(0, x.lastIndexOf('.')) || x; This works because an empty string is falsy, therefore it returns x.
I like this one because it is a one liner which isn't too hard to read:
In Node.js versions prior to 0.12.x:
Of course this also works in 0.12.x and later.
I don't know if it's a valid option but I use this:
It's not just one operation I know, but at least it should always work!
It should not be name.join('') but name.join('.'). You split by dot but join by comma, so hello.name.txt returns hello, name
This works, even when the delimiter is not present in the string.
Can also be used as a one-liner like this:
EDIT: This is a more efficient solution:
Here's another regex-based solution:
This should only chop off the last segment.
The accepted answer strips the last extension part only ( .jpg ), which might be a good choice in most cases.
I once had to strip all extensions ( .tar.gz ) and the file names were restricted to not contain dots (so 2015-01-01.backup.tar would not be a problem):
I like this answer. to add to it: If you know the extension beforehand (or if the extension is a variable, then I find it more readable to say: filename.slice(0, -'.zip'.length) or filename.slice(0, -extension.length) .
If you have to process a variable that contains the complete path (ex.: thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg" ) and you want to return just "filename" you can use:
the result will be theName == "filename";
To try it write the following command into the console window of your chrome debugger: window.location.pathname.split("/").slice(-1).join().split(".").shift()
If you have to process just the file name and its extension (ex.: theNameWithExt = "filename.jpg" ):
the result will be theName == "filename", the same as above;
Читайте также: