如何从 JavaScript 中的字符串修剪文件扩展名?
Posted
技术标签:
【中文标题】如何从 JavaScript 中的字符串修剪文件扩展名?【英文标题】:How to trim a file extension from a String in JavaScript? 【发布时间】:2011-05-14 02:47:44 【问题描述】:例如,假设x = filename.jpg
,我想得到filename
,其中filename
可以是任何文件名(我们假设文件名只包含[a-zA-Z0-9-_]以简化.).
我在DZone Snippets 上看到了x.substring(0, x.indexOf('.jpg'))
,但x.substring(0, x.length-4)
的表现不是更好吗?因为length
是一个属性,不做字符检查,而indexOf()
是一个函数,做字符检查。
【问题讨论】:
见:Regular expression to remove a file's extension,另见:How can i get file extensions with javascript? 和***.com/questions/1991608/…差不多。除非你做很多这样的事情,否则担心效率就是过早的优化。 在 ES6 时代,还可以查看 Path 模块——以防你使用的是 nodejs 或适当的转译 【参考方案1】:我喜欢使用正则表达式来做到这一点。它简短易懂。
for (const regexPattern of [
/\..+$/, // Find the first dot and all the content after it.
/\.[^/.]+$/ // Get the last dot and all the content after it.
])
console.log("myFont.ttf".replace(regexPattern, ""))
console.log("myFont.ttf.log".replace(regexPattern, ""))
/* output
myFont
myFont
myFont
myFont.ttf
*/
上面的解释可能不是很严谨。如果想得到更准确的解释可以去regex101查看
\..+$ \.[^/.]+$【讨论】:
【参考方案2】:在node.js中,不带扩展名的文件名可以如下获取。
const path = require('path');
const filename = 'hello.html';
path.parse(filename).name; //=> "hello"
path.parse(filename).ext; //=> ".html"
path.parse(filename).base; //=> "hello.html"
Node.jsdocumentation 页面的进一步解释。
【讨论】:
这个答案仅限于服务器端节点。如果您尝试在反应代码中使用它,它似乎不会导入。 如果您想从包含目录的路径中删除扩展名,您可以执行var parsed = path.parse(filename)
后跟path.join(parsed.dir, parsed.name)
。
另一种可能是let base = path.basename( file_path, path.extname( file_path ) )
。【参考方案3】:
如果知道扩展名的长度,可以使用x.slice(0, -4)
(其中4是扩展名和点的三个字符)。
如果您不知道长度,@John Hartsock regex 将是正确的方法。
如果你不想使用正则表达式,你可以试试这个(性能较差):
filename.split('.').slice(0, -1).join('.')
请注意,它会在没有扩展名的文件上失败。
【讨论】:
我最喜欢这个解决方案。它很干净,我可以使用它,因为我知道文件扩展名始终是.jpg
。我一直在寻找像 Ruby 的 x[0..-5]
和 x.slice(0, -4)
之类的东西,看起来很棒!谢谢!并感谢其他所有人提供的所有其他强大的替代方案!
这不是最佳解决方案,请查看以下其他解决方案。
如果你不能 100% 确定扩展的长度,那么不要这样:"picture.jpeg".slice(0, -4)
-> "picture."
这是一个危险的解决方案,因为你并不真正知道格式的长度。
"如果你知道扩展的长度" 几十年前,这是一个可以接受的假设。不要再使用这个了。【参考方案4】:
Node.js 从完整路径保存目录中删除扩展
https://***.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://***.com/a/36099196/895245 也实现了这一点,但我发现这种方法在语义上更令人愉悦。
在 Node.js v10.15.2 中测试。
【讨论】:
【参考方案5】:我不知道这是否是一个有效的选项,但我使用这个:
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('.')
【讨论】:
不应该是name.join(''),而是name.join('.')。你用点分隔,但用逗号连接,所以hello.name.txt
返回hello, name
文件名.split(".").shift();【参考方案6】:
虽然已经很晚了,但我将添加另一种方法来使用普通的旧 JS 获取不带扩展名的文件名-
path.replace(path.substr(path.lastIndexOf('.')), '')
【讨论】:
或path.split('.').pop()
用于部分文件扩展名
他实际上是在尝试获取文件名,而不是扩展名!【参考方案7】:
我喜欢这个,因为它是一个不难阅读的单行:
filename.substring(0, filename.lastIndexOf('.')) || filename
【讨论】:
【参考方案8】:这是我用来从文件名中删除扩展名的代码,不使用正则表达式或 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 谢谢你是对的,我忘了读取文件扩展名。我已经更新了答案,我希望它现在可以工作。【参考方案9】:
x.slice(0, -(x.split('.').pop().length + 1));
【讨论】:
虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。【参考方案10】: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");
OR(假设文件名只有一个点)
parts = x.match(/[^\.]+/);
x = parts[0];
OR(也只有一个点)
parts = x.split(".");
x = parts[0];
【讨论】:
?? 在这种情况下,您可以有一个文件名,例如:“summer.family.jpg” split('.')[0]将仅返回部分文件名。我会从答案中删除该问题,或者在该示例的问题下明确说明。 @basarat ... 关于零件分割我经常做的事情:var parts = full_file.split("."); var ext = parts[parts.length-1]; var file = parts.splice(0,parts.length-1).join(".");
x.split(".") 甚至不应被视为答案。我知道我使用“。”在我几乎所有的文件命名约定中,即“survey.controller.js”或“my.family.jpg”。
@Lee2808:因此只有一个点的警告。这只是为了表明存在多种方法,具体取决于应用程序。在几乎所有情况下,我肯定会使用其他方法之一。
x = x.substr(0, x.lastIndexOf('.'));
- 你的意思可能是x = x.substring(0, x.lastIndexOf('.'));
?【参考方案11】:
如果您必须处理包含完整路径的变量(例如:thePath = "http://***.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",同上;
注意事项:
-
第一个有点慢,因为执行得更多
操作;但在这两种情况下都有效,换句话说,它可以提取
来自给定字符串的不带扩展名的文件名,该字符串包含路径或带有 ex 的文件名。而第二种方法仅在给定变量包含带有 ext 的文件名(如 filename.ext)时才有效,但要快一些。
这两种解决方案都适用于本地文件和服务器文件;
但我不能说与其他答案的性能比较以及浏览器或操作系统的兼容性。
working sn-p 1:完整路径
var thePath = "http://***.com/directory/subdirectory/filename.jpg";
theName = thePath.split("/").slice(-1).join().split(".").shift();
alert(theName);
working sn-p 2:带扩展名的文件名
var theNameWithExt = "filename.jpg";
theName = theNameWithExt.split("/").slice(-1).join().split(".").shift();
alert(theName);
working sn-p 2: 双扩展名的文件名
var theNameWithExt = "filename.tar.gz";
theName = theNameWithExt.split("/").slice(-1).join().split(".").shift();
alert(theName);
【讨论】:
【参考方案12】:简单一:
var n = str.lastIndexOf(".");
return n > -1 ? str.substr(0, n) : str;
【讨论】:
【参考方案13】:您可以使用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'
【讨论】:
【参考方案14】:不确定什么会执行得更快,但是当涉及到.jpeg
或.html
等扩展时,这会更可靠
x.replace(/\.[^/.]+$/, "")
【讨论】:
您可能还想禁止 / 作为路径分隔符,因此正则表达式为 /\.[^/.]+$/ 这适用于任何长度的文件扩展名(.txt 或 .html 或 .htaccess),并且还允许文件名包含额外的句点 (.) 字符。它不会处理例如 .tar.gz 由于扩展本身包含一个句点。文件名包含附加句点比文件扩展名更常见。谢谢! @Vik “正确答案”和接受的答案之间存在差异。接受的答案就是对提出问题的人有帮助的答案。 我认为 Windows 平台可能存在问题,因为可能存在反斜杠。所以正则表达式应该是 /\.[^/\\.]+$/. @ElgsQianChen 这里是帮助您回答问题的好工具regexr.com【参考方案15】:var fileName = "something.extension";
fileName.slice(0, -path.extname(fileName).length) // === "something"
【讨论】:
这是迄今为止唯一适用于完整路径的方法:path/name.ext
-> paht/name
而不是仅仅返回name
,但我宁愿使用fs.parse
,尽管它是更详细一点:***.com/a/59576950/895245
我喜欢这个答案......添加到它:如果您事先知道扩展名(或者如果扩展名是一个变量,那么我觉得这样说:filename.slice(0, -'.zip'.length)
或 @987654328 @.【参考方案16】:
在 0.12.x 之前的 Node.js 版本中:
path.basename(filename, path.extname(filename))
当然这也适用于 0.12.x 及更高版本。
【讨论】:
path.parse
answer 更简单。【参考方案17】:
接受的答案仅去除最后一个扩展部分 (.jpeg
),这在大多数情况下可能是一个不错的选择。
我曾经不得不删除所有扩展名 (.tar.gz
),并且文件名被限制为不包含点(所以 2015-01-01.backup.tar
不会有问题):
var name = "2015-01-01_backup.tar.gz";
name.replace(/(\.[^/.]+)+$/, "");
【讨论】:
【参考方案18】:这是另一个基于正则表达式的解决方案:
filename.replace(/\.[^.$]+$/, '');
这应该只切断最后一段。
【讨论】:
【参考方案19】:即使字符串中不存在分隔符,这也有效。
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 + ""
【讨论】:
【参考方案20】:另一种衬里 - 我们假设我们的文件是 jpg 图片 >> 例如:var yourStr = 'test.jpg';
yourStr = yourStr.slice(0, -4); // 'test'
【讨论】:
【参考方案21】:您也许可以假设最后一个点将是扩展分隔符。
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);
【讨论】:
警告,如果碰巧没有文件扩展名,则会失败。剩下一个空字符串。 不考虑点的较短版本。var f = x.substr(0, x.lastIndexOf('.')) || x;
这是有效的,因为空字符串是虚假的,因此它返回 x。【参考方案22】:
另一条线:
x.split(".").slice(0, -1).join(".")
【讨论】:
【参考方案23】:这就是正则表达式派上用场的地方! Javascript 的 .replace()
方法将采用正则表达式,您可以利用它来完成您想要的:
// assuming var x = filename.jpg or some extension
x = x.replace(/(.*)\.[^.]+$/, "$1");
【讨论】:
【参考方案24】:我会使用类似 x.substring(0, x.lastIndexOf('.')) 的东西。如果您要追求性能,那就根本不要使用 javascript :-p 不,再多一条语句对于 99.99999% 的所有用途来说确实无关紧要。
【讨论】:
“如果你追求性能,就不要使用 javascript” - 你还建议在 Web 应用程序中使用什么......? 他没有提到网络应用程序。 这个问题是在 7 年前的 2010 年提出的,答案是在 2010 年发布的,当时 JavaScript 几乎只在 Web 应用程序中使用。 (Node 刚刚诞生,当时它甚至没有指南,也没有 NPM) ;-) 不过,如果性能对此类任务很重要,您可以考虑在后端执行此操作并在前端处理结果。以上是关于如何从 JavaScript 中的字符串修剪文件扩展名?的主要内容,如果未能解决你的问题,请参考以下文章