简体   繁体   English

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

[英]How to trim a file extension from a String in JavaScript?

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.).例如,假设x = filename.jpg ,我想获取filename ,其中filename可以是任何文件名(我们假设文件名仅包含 [a-zA-Z0-9-_] 以简化。)。

I saw x.substring(0, x.indexOf('.jpg')) on DZone Snippets , but wouldn't x.substring(0, x.length-4) perform better?我在DZone Snippets上看到x.substring(0, x.indexOf('.jpg')) ,但x.substring(0, x.length-4)不会表现更好吗? Because, length is a property and doesn't do character checking whereas indexOf() is a function and does character checking.因为, length是一个属性并且不进行字符检查,而indexOf()是一个 function 并且进行字符检查。

不确定什么会执行得更快,但是当涉及到.jpeg.html之类的扩展名时,这会更可靠

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

In node.js , the name of the file without the extension can be obtained as follows.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"

Further explanation at Node.js documentation page. Node.js文档页面的进一步解释。

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

If you don't know the length @John Hartsock regex would be the right approach.如果您不知道长度@John Hartsock正则表达式将是正确的方法。

If you'd rather not use regular expressions, you can try this (less performant):如果您不想使用正则表达式,可以试试这个(性能较差):

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

Note that it will fail on files without extension.请注意,它会在没有扩展名的文件上失败。

x.length-4 only accounts for extensions of 3 characters. x.length-4仅考虑 3 个字符的扩展名。 What if you have filename.jpeg or filename.pl ?如果你有filename.jpegfilename.pl怎么办?

EDIT:编辑:

To answer... sure, if you always have an extension of .jpg , x.length-4 would work just fine.回答......当然,如果你总是有.jpg的扩展名, x.length-4就可以了。

However, if you don't know the length of your extension, any of a number of solutions are better/more robust.但是,如果您不知道扩展的长度,那么许多解决方案中的任何一个都更好/更健壮。

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

OR或者

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

OR或者

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

OR (with the assumption filename only has one dot)或(假设文件名只有一个点)

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

OR (also with only one dot)或(也只有一个点)

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

You can perhaps use the assumption that the last dot will be the extension delimiter.您也许可以假设最后一个点将是扩展分隔符。

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

If file has no extension, it will return empty string.如果文件没有扩展名,它将返回空字符串。 To fix that use this function要解决此问题,请使用此功能

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

我喜欢这个,因为它是一个不太难读的单行:

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

In Node.js versions prior to 0.12.x:在 0.12.x 之前的 Node.js 版本中:

path.basename(filename, path.extname(filename))

Of course this also works in 0.12.x and later.当然,这也适用于 0.12.x 及更高版本。

I don't know if it's a valid option but I use this:我不知道这是否是一个有效的选项,但我使用这个:

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.

It's not just one operation I know, but at least it should always work!这不仅仅是我知道的一项操作,但至少它应该始终有效!

UPDATE: If you want a oneliner, here you are:更新:如果你想要一个 oneliner,你在这里:

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

This works, even when the delimiter is not present in the string.即使字符串中不存在分隔符,这也有效。

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"

Can also be used as a one-liner like this:也可以像这样用作单线:

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

EDIT: This is a more efficient solution:编辑:这是一个更有效的解决方案:

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

另一个单行:

x.split(".").slice(0, -1).join(".")

This can also be done easily with path using the basename and extname methods. 使用basename和extname方法也可以使用path轻松完成此操作。

const path = require('path')

path.basename('test.txt', path.extname('test.txt'))

Here's another regex-based solution:这是另一个基于正则表达式的解决方案:

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

This should only chop off the last segment.这应该只切断最后一段。

Simple one:简单一:

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

The accepted answer strips the last extension part only ( .jpeg ), which might be a good choice in most cases.接受的答案仅去除最后一个扩展部分( .jpeg ),这在大多数情况下可能是一个不错的选择。

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):我曾经不得不删除所有扩展名( .tar.gz )并且文件名被限制为不包含点(所以2015-01-01.backup.tar不会有问题):

var name = "2015-01-01_backup.tar.gz";
name.replace(/(\.[^/.]+)+$/, "");
var fileName = "something.extension";
fileName.slice(0, -path.extname(fileName).length) // === "something"

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

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

the result will be theName == "filename" ;结果将是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()要尝试它,请将以下命令写入 chrome 调试器的控制台窗口: 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" ):如果您只需要处理文件名及其扩展名(例如: theNameWithExt = "filename.jpg" ):

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

the result will be theName == "filename" , the same as above;结果将是theName == "filename" ,同上;

Notes:笔记:

  1. 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.但在这两种情况下都有效,换句话说,它可以从包含路径或带有 ex 的文件名的给定字符串中提取不带扩展名的文件名。 While the second works only if the given variable contains a filename with ext like filename.ext but is a little bit quicker.而第二个仅在给定变量包含带有 ext 的文件名(如 filename.ext)时才有效,但要快一些。
  2. 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.但我不能说与其他答案的性能比较以及浏览器或操作系统的兼容性。

working snippet 1: the complete path工作片段 1:完整路径

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

working snippet 2: the file name with extension工作片段 2:带扩展名的文件名

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

working snippet 2: the file name with double extension工作片段 2:具有双扩展名的文件名

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

Node.js remove extension from full path keeping directory Node.js 从完整路径保存目录中删除扩展

https://stackoverflow.com/a/31615711/895245 for example did path/hello.html -> hello , but if you want path/hello.html -> path/hello , you can use this: 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));

outputs directory as well:输出目录:

path/hello

https://stackoverflow.com/a/36099196/895245 also achieves this, but I find this approach a bit more semantically pleasing. https://stackoverflow.com/a/36099196/895245也实现了这一点,但我发现这种方法在语义上更令人愉悦。

Tested in Node.js v10.15.2.在 Node.js v10.15.2 中测试。

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

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

This is the code I use to remove the extension from a filename, without using either regex or indexOf (indexOf is not supported in IE8).这是我用来从文件名中删除扩展名的代码,不使用正则表达式或 indexOf(IE8 不支持 indexOf)。 It assumes that the extension is any text after the last '.'它假定扩展名是最后一个 '.' 之后的任何文本。 character.特点。

It works for:它适用于:

  • files without an extension: "myletter"没有扩展名的文件:“myletter”
  • files with '.'带有 '.' 的文件in the name: "my.letter.txt"在名称中:“my.letter.txt”
  • unknown length of file extension: "my.letter.html"未知长度的文件扩展名:“my.letter.html”

Here's the code:这是代码:

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

You can use path to maneuver.您可以使用path进行机动。

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

Output输出

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

This is where regular expressions come in handy!这就是正则表达式派上用场的地方! Javascript's .replace() method will take a regular expression, and you can utilize that to accomplish what you want: Javascript 的.replace()方法将采用正则表达式,您可以利用它来完成您想要的:

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

I like to use the regex to do that.我喜欢使用正则表达式来做到这一点。 It's short and easy to understand.它简短易懂。

 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 */

The above explanation may not be very rigorous.上面的解释可能不是很严谨。 If you want to get a more accurate explanation can go to regex101 to check如果想得到更准确的解释可以去regex101查看

We might come across filename or file path with multiple extension suffix.我们可能会遇到带有多个扩展名后缀的文件名或文件路径。 Consider the following to trim them.考虑以下内容来修剪它们。

text = "/dir/path/filename.tar.gz"    
output = text.replace(/(\.\w+)+$/,"")

result of output: "/dir/path/filename"输出结果:“/dir/path/filename”

It solves the file extension problem especially when the input has multiple extensions.它解决了文件扩展名问题,尤其是当输入具有多个扩展名时。

  • A straightforward answer, if you are using Node.js, is the one in the first comment.如果您使用的是 Node.js,一个简单的答案是第一条评论中的答案。
  • My problem was I need to delete an image in Cloudinary from the Node server.我的问题是我需要从 Node 服务器中删除 Cloudinary 中的图像。 I just need to get the image name.我只需要获取图像名称。 Example:例子:
const path = require("path")
const image=xyz.jpg;
const img= path.parse(image).name
console.log(img) // xyz

另一种衬里 - 我们假设我们的文件是 jpg 图片 >> 例如:var yourStr = 'test.jpg';

    yourStr = yourStr.slice(0, -4); // 'test'
x.slice(0, -(x.split('.').pop().length + 1));

First you have to get correct the extension of file then you can remove it 首先,你必须得到正确的文件扩展名,然后你可以删除它

try this code 试试这段代码

<!DOCTYPE html>
<html>
<body>
<p>Click the button to display the array values after the split.</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
function getFileName(str){
    var res = str.split('.').pop();
    alert('filename: ' + str.replace('.' + res, ''));
    alert('extension: ' +res);
}
function myFunction() {
    getFileName('abc.jpg');
    getFileName('abc.def.jpg');
    getFileName('abc.def.ghi.jpg');
    getFileName('abc.def.ghi.123.jpg');
    getFileName('abc.def.ghi.123.456.jpg');
    getFileName('abc.jpg.xyz.jpg'); // test with Sébastien comment lol
}
</script>
</body>
</html>
name.split('.').slice(0, -1).join('.')

这就是享受你的编码......

I would use something like x.substring(0, x.lastIndexOf('.')).我会使用类似 x.substring(0, x.lastIndexOf('.')) 的东西。 If you're going for performance, don't go for javascript at all :-p No, one more statement really doesn't matter for 99.99999% of all purposes.如果您要追求性能,则根本不要使用 javascript :-p 不,再多一条语句对于 99.99999% 的所有目的都无关紧要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM