如何从JavaScript中的字符串修剪文件扩展名?


295

例如,假设x = filename.jpg,我想得到filename,其中filename可以是任何文件名(让我们假设该文件名仅包含[a-zA-Z0-9-_]来简化。)。

x.substring(0, x.indexOf('.jpg'))DZone片段上看到了,但是效果会x.substring(0, x.length-4)更好吗?因为,length是属性,不进行字符检查,indexOf()而是函数,则进行字符检查。



stackoverflow.com/questions/1991608/…几乎相同。除非您做到其中之一,否则担心效率就是过早的优化。
原型保罗

在ES6的年龄,也看到了路径模块-如果你正在使用或的NodeJS适当transpilation
弗兰克Nocke

Answers:


173

如果知道扩展名的长度,则可以使用x.slice(0, -4)(其中4是扩展名和点的三个字符)。

如果您不知道@John Hartsock regex的长度是正确的方法。

如果您不想使用正则表达式,则可以尝试以下方法(性能较低):

filename.split('.').slice(0, -1).join('.')

请注意,它将在没有扩展名的文件上失败。


我最喜欢这种解决方案。它很干净,我可以使用它,因为我知道文件扩展名始终为.jpg。我一直在寻找Ruby的东西x[0..-5]x.slice(0, -4)看起来很棒!谢谢!并感谢其他所有人提供的所有其他强大替代方案!
ma11hew28 2010年

22
这不是最佳解决方案,请检查以下其他解决方案。
bunjeeb 2015年

8
而且,如果您不确定扩展名的长度,请不要这样做:"picture.jpeg".slice(0, -4)->“图片”。
basic6

13
这是危险的解决方案,因为您实际上并不知道格式的长度。
编码员

“如果您知道扩展名的长度”,这是几十年来可以接受的假设。不要再使用了。
亚历山大-

453

不知道会执行得更快,但是当涉及到分机这样会更可靠.jpeg.html

x.replace(/\.[^/.]+$/, "")

15
您可能还想禁止/作为路径分隔符,因此正则表达式为/\.[^/.]+$/
gsnedders

这适用于任何长度的文件扩展名(.txt或.html或.htaccess),并且还允许文件名包含其他句点(。)字符。由于扩展名本身包含句点,因此无法处理.tar.gz。文件名包含额外的句点比文件扩展名更常见。谢谢!
史蒂夫·西格

2
@Vik“正确答案”和公认答案之间是有区别的。可接受的答案只是对提出该问题的人有用的答案。
史蒂文(Steven)

4
我想Windows平台可能存在问题,因为可能会有反斜线。因此,正则表达式应为/\.[^/\\.]+$/。
亚历克斯·楚夫

1
@ElgsQianChen这是一个很好的工具,可以帮助您回答问题regexr.com
John Hartsock

279

node.js中,不带扩展名的文件名可以按以下方式获取。

const path = require('path');
const filename = 'hello.html';

path.parse(filename).name; // hello
path.parse(filename).ext;  // .html

Node.js 文档页面上的进一步说明。


2
您在说什么@kaasdude...。此方法有效地删除了node上的扩展名。不确定要表达的内容,但是此方法适用于珍珠。
埃里克(Erick)'18

1
这个答案非常限于服务器端节点。如果您尝试在react代码中使用它,它似乎不会导入。
查理

1
如果你想删除包括目录的路径延伸,你可以做var parsed = path.parse(filename)后面path.join(parsed.dir, parsed.name)
Jespertheend

另一种可能性是let base = path.basename( file_path, path.extname( file_path ) )
bicarlsen

116

x.length-4仅占3个字符的扩展名。如果有filename.jpeg或该filename.pl怎么办?

编辑:

要回答...当然,如果您始终使用的扩展名.jpg,则x.length-4可以正常工作。

但是,如果您不知道扩展名的长度,那么许多解决方案中的任何一种都会更好/更可靠。

x = x.replace(/\..+$/, '');

要么

x = x.substring(0, x.lastIndexOf('.'));

要么

x = x.replace(/(.*)\.(.*?)$/, "$1");

或(假设文件名只有一个点)

parts = x.match(/[^\.]+/);
x = parts[0];

或(也只有一个点)

parts = x.split(".");
x = parts[0];

12
?? 您可以使用一个文件名,例如:“ summer.family.jpg”,在这种情况下,split('。')[0]将仅返回部分文件名。我会从答案中删除那个,或者在该示例的问题下方清楚说明。@basarat ...
Roko C. Buljan

我经常做的关于零件分割的事情:var parts = full_file.split("."); var ext = parts[parts.length-1]; var file = parts.splice(0,parts.length-1).join(".");
radicand

x.split(“。”)甚至不应被视为答案。我知道我使用“。” 在几乎所有文件命名约定中,即“ survey.controller.js”或“ my.family.jpg”。
李布林德里

@ Lee2808:因此仅警告一个点。这仅是为了表明有多种方法,具体取决于应用程序。在几乎所有情况下,我当然都会使用其他方法之一。
杰夫·B

x = x.substr(0, x.lastIndexOf('.'));-你可能是说x = x.substring(0, x.lastIndexOf('.'));什么?
Dziad Borowy '17

39

您也许可以假设最后一个点将是扩展定界符。

var x = 'filename.jpg';
var f = x.substr(0, x.lastIndexOf('.'));

如果文件没有扩展名,它将返回空字符串。要解决此问题,请使用此功能

function removeExtension(filename){
    var lastDotPosition = filename.lastIndexOf(".");
    if (lastDotPosition === -1) return filename;
    else return filename.substr(0, lastDotPosition);
}

警告,如果碰巧没有文件扩展名,则失败。您剩下一个空字符串。
布拉德

18
较短的版本不占点。var f = x.substr(0, x.lastIndexOf('.')) || x;这是有效的,因为空字符串是虚假的,因此它返回x。
乔纳森·罗尼

21

我喜欢这个,因为它是一根很难读的内胆:

filename.substring(0, filename.lastIndexOf('.')) || filename


12

即使在字符串中不存在分隔符的情况下,此方法也有效。

String.prototype.beforeLastIndex = function (delimiter) {
    return this.split(delimiter).slice(0,-1).join(delimiter) || this + ""
}

"image".beforeLastIndex(".") // "image"
"image.jpeg".beforeLastIndex(".") // "image"
"image.second.jpeg".beforeLastIndex(".") // "image.second"
"image.second.third.jpeg".beforeLastIndex(".") // "image.second.third"

也可以像这样用作单线:

var filename = "this.is.a.filename.txt";
console.log(filename.split(".").slice(0,-1).join(".") || filename + "");

编辑:这是一个更有效的解决方案:

String.prototype.beforeLastIndex = function (delimiter) {
    return this.substr(0,this.lastIndexOf(delimiter)) || this + ""
}

10

我不知道这是不是一个有效的选项,但是我使用了这个:

name = filename.split(".");
// trimming with pop()
name.pop();
// getting the name with join()
name.join('.'); // we split by '.' and we join by '.' to restore other eventual points.

我知道这不仅是一项操作,而且至少应该可以正常运行!

更新:如果您想要一个内衬,您在这里:

(name.split('.').slice(0, -1)).join('.')


1
它不应该是name.join(''),而是name.join('。')。您按点分隔,但用逗号分隔,因此hello.name.txt返回hello, name
Evil


7

这是另一个基于正则表达式的解决方案:

filename.replace(/\.[^.$]+$/, '');

这仅应切掉最后一段。


7

简单的一个:

var n = str.lastIndexOf(".");
return n > -1 ? str.substr(0, n) : str;

6

可接受的答案仅剥离最后一个扩展部分(.jpeg),这在大多数情况下可能是一个不错的选择。

我曾经不得不去除所有扩展名(.tar.gz),并且文件名被限制为不包含点(因此2015-01-01.backup.tar不会有问题):

var name = "2015-01-01_backup.tar.gz";
name.replace(/(\.[^/.]+)+$/, "");


3

如果您必须处理包含完整路径的变量(例如:),thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg"并且只想返回“文件名”,则可以使用:

theName = thePath.split("/").slice(-1).join().split(".").shift();

结果将是theName ==“ filename” ;

要进行尝试,请将以下命令写入chrome调试器的控制台窗口: window.location.pathname.split("/").slice(-1).join().split(".").shift()

如果您只需要处理文件名及其扩展名(例如:)theNameWithExt = "filename.jpg"

theName = theNameWithExt.split(".").shift();

结果将是theName ==“ filename”,与上面相同;

笔记:

  1. 第一个有点慢,因为它执行更多的操作;但在两种情况下都可以使用,换句话说,它可以从包含路径或文件名带有ex的给定字符串中提取文件名而无需扩展名。尽管第二个方法仅在给定变量包含带有ext的文件名(如filename.ext)的情况下有效,但要快一些。
  2. 两种解决方案都适用于本地文件和服务器文件。

但是我既不能与其他答案进行性能比较,也不能与浏览器或操作系统兼容。

工作片段1:完整路径

var thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg";
theName = thePath.split("/").slice(-1).join().split(".").shift();
alert(theName);
  

工作片段2:带有扩展名的文件名

var theNameWithExt = "filename.jpg";
theName = theNameWithExt.split("/").slice(-1).join().split(".").shift();
alert(theName);
  

工作片段2:具有双扩展名的文件名

var theNameWithExt = "filename.tar.gz";
theName = theNameWithExt.split("/").slice(-1).join().split(".").shift();
alert(theName);
  


3

尽管已经很晚了,但我将添加另一种方法,使用普通的旧JS-来获取不带扩展名的文件名

path.replace(path.substr(path.lastIndexOf('.')), '')


path.split('.').pop()一部分文件扩展名
mixdev

他实际上是在尝试获取文件名,而不是扩展名!
Munim Dibosh,

3

Node.js从完整路径保留目录中删除扩展名

https://stackoverflow.com/a/31615711/895245例如做到了path/hello.html-> hello,但是如果您想要path/hello.html-> path/hello,则可以使用以下命令:

#!/usr/bin/env node
const path = require('path');
const filename = 'path/hello.html';
const filename_parsed = path.parse(filename);
console.log(path.join(filename_parsed.dir, filename_parsed.name));

也输出目录:

path/hello

https://stackoverflow.com/a/36099196/895245也可以实现这一点,但是我发现这种方法在语义上更加令人愉悦。

在Node.js v10.15.2。中测试


0

这是正则表达式派上用场的地方!Javascript的.replace()方法将采用正则表达式,您可以利用它来完成所需的操作:

// assuming var x = filename.jpg or some extension
x = x.replace(/(.*)\.[^.]+$/, "$1");

0

另一个衬板-我们假定文件是jpg图片>>例如:var yourStr ='test.jpg';

    yourStr = yourStr.slice(0, -4); // 'test'

0

您可以使用path机动。

var MYPATH = '/User/HELLO/WORLD/FILENAME.js';
var MYEXT = '.js';
var fileName = path.basename(MYPATH, MYEXT);
var filePath = path.dirname(MYPATH) + '/' + fileName;

输出量

> filePath
'/User/HELLO/WORLD/FILENAME'
> fileName
'FILENAME'
> MYPATH
'/User/HELLO/WORLD/FILENAME.js'


0

这是我用来从文件名中删除扩展名的代码,而不使用regex或indexOf(IE8不支持indexOf)。它假定扩展名是最后一个“。”之后的任何文本。字符。

它适用于:

  • 没有扩展名的文件:“ Myletter”
  • 带有“。”的文件 在名称中:“ my.letter.txt”
  • 文件扩展名的长度未知:“ my.letter.html”

这是代码:

var filename = "my.letter.txt" // some filename

var substrings = filename.split('.'); // split the string at '.'
if (substrings.length == 1)
{
  return filename; // there was no file extension, file was something like 'myfile'
}
else
{
  var ext = substrings.pop(); // remove the last element
  var name = substrings.join(""); // rejoin the remaining elements without separator
  name = ([name, ext]).join("."); // readd the extension
  return name;
}

失败hello.tar.gz,输出为hellotar
阿西夫·阿里

#AsifAli,谢谢您,我忘了阅读文件扩展名。我已经更新了答案,希望现在可以使用。
Little Brain

-3

我会使用x.substring(0,x.lastIndexOf('。'))之类的东西。如果您要提高性能,那么根本不要使用javascript:-p不,对于99.99999%的所有用途,再声明一次并不重要。


2
“如果要提高性能,请不要使用javascript” -您建议在Web应用程序中使用其他什么。
TJ

他没有提到Web应用程序。
卢卡斯·莫斯科普斯

1
在7年前的2010年,有人问过这个问题,并回答了这个问题,而JavaScript仅在Web应用程序中被广泛使用。(Node刚出生,当时甚至没有向导或NPM)
TJ

;-)但是,如果性能对此类任务很重要,则可以考虑在后端执行此操作,并在前端处理结果。
卢卡斯·莫斯科普斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.