如何在JavaScript中修剪String中的文件扩展名?

ma1*_*w28 266 javascript replace substring indexof substr

例如,假设x = filename.jpg我想知道filename,哪里filename可以是任何文件名(假设文件名只包含[a-zA-Z0-9-_]以简化.).

x.substring(0, x.indexOf('.jpg'))DZone Snippets上看过,但效果会不会x.substring(0, x.length-4)更好?因为,length是一个属性,不进行字符检查,indexOf()而是一个函数,并进行字符检查.

Joh*_*ock 427

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

x.replace(/\.[^/.]+$/, "")
Run Code Online (Sandbox Code Playgroud)

  • 您可能还想禁用/作为路径分隔符,因此正则表达式为/\.[^ /.] + $ / (15认同)
  • @Vik“正确答案”和公认答案之间是有区别的。可接受的答案只是对提出该问题的人有用的答案。 (2认同)
  • 我想Windows平台可能存在问题,因为可能存在反斜杠.所以regexp应该是/\.[^ /\\.]+$/. (2认同)
  • @ElgsQianChen 这里是一个很好的工具,可以帮助您回答问题 https://regexr.com/ (2认同)

Jib*_*tra 213

node.js中,可以如下获得没有扩展名的文件的名称.

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

path.parse(filename).name; // hello
path.parse(filename).ext;  // .html
Run Code Online (Sandbox Code Playgroud)

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

  • 如果要从包含目录的路径中删除扩展名,可以执行“var parsed = path.parse(filename)”,然后执行“path.join(parsed.dir, parsed.name)”。 (3认同)
  • 你在谈论@kaasdude ....这个方法有效地删除了节点上的扩展.不知道你想要表达什么,但这个方法适用于珍珠. (2认同)
  • 这个答案仅限于服务器端节点。如果您尝试在 React 代码中使用它,它似乎不会导入。 (2认同)
  • 另一种可能性是“let base = path.basename( file_path, path.extname( file_path ) )”。 (2认同)

Mar*_*ota 146

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

如果你不知道长度@John Hartsock正则表达式将是正确的方法.

如果你不想使用正则表达式,你可以试试这个(效率较低):

filename.split('.').slice(0, -1).join('.')
Run Code Online (Sandbox Code Playgroud)

请注意,没有扩展名的文件将失败.

  • 这不是最佳解决方案,请查看下面的其他解决方案. (16认同)
  • 这是危险的解决方案,因为您实际上并不知道格式的长度. (13认同)
  • 如果你不是100%确定扩展的长度,那么不要这样:`"picture.jpeg".slice(0,-4)` - >"picture". (8认同)

Jef*_*f B 113

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];
Run Code Online (Sandbox Code Playgroud)

或(也只有一个点)

parts = x.split(".");
x = parts[0];
Run Code Online (Sandbox Code Playgroud)

  • **??**你可以有一个文件名ex:"summer.family.jpg"在这种情况下**split('.')[0]**将只返回部分文件名.我会从答案中删除那个,或者清楚地说明该例子的问题.@basarat ...... (10认同)

Mar*_*ten 38

您也许可以使用最后一个点将是扩展分隔符的假设.

var x = 'filename.jpg';
var f = x.substr(0, x.lastIndexOf('.'));
Run Code Online (Sandbox Code Playgroud)

如果file没有扩展名,则返回空字符串.要修复它使用此功能

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

  • 更短的版本,没有点.`var f = x.substr(0,x.lastIndexOf('.'))|| x;`这是因为空字符串是假的,因此它返回x. (16认同)

bla*_*238 16

在0.12.x之前的Node.js版本中:

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

当然这也适用于0.12.x及更高版本.


jak*_*zon 12

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

filename.substring(0, filename.lastIndexOf('.')) || filename
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是最好的,因为它真的很容易理解 (2认同)

And*_*ank 11

即使字符串中不存在分隔符,这也可以工作.

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"
Run Code Online (Sandbox Code Playgroud)

也可以用作这样的单线:

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

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

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


DBr*_*own 9

使用basename和extname方法,也可以通过path轻松完成此操作。

const path = require('path')

path.basename('test.txt', path.extname('test.txt'))
Run Code Online (Sandbox Code Playgroud)


Gia*_*one 8

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

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.
Run Code Online (Sandbox Code Playgroud)

这不仅仅是我所知道的一项操作,但至少它应该始终有效!

更新:如果你想要一个oneliner,你在这里:

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


Jac*_*ard 7

另一个单线:

x.split(".").slice(0, -1).join(".")
Run Code Online (Sandbox Code Playgroud)


Cha*_*son 6

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

filename.replace(/\.[^.$]+$/, '');
Run Code Online (Sandbox Code Playgroud)

这应该只切断最后一段.


bas*_*ic6 6

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

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

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


Yas*_*Yas 6

var fileName = "something.extension";
fileName.slice(0, -path.extname(fileName).length) // === "something"
Run Code Online (Sandbox Code Playgroud)


小智 6

简单的一个:

var n = str.lastIndexOf(".");
return n > -1 ? str.substr(0, n) : str;
Run Code Online (Sandbox Code Playgroud)


Moh*_*aud 6

  • 如果您使用 Node.js,第一个评论中的答案就是一个简单的答案。
  • 我的任务是需要从 Node 服务器删除 Cloudinary 中的图像,并且只需要获取图像名称。例子:
const path = require("path")
const image=xyz.jpg;
const img= path.parse(image).name
console.log(img) // xyz
Run Code Online (Sandbox Code Playgroud)


wil*_*nka 5

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

theName = thePath.split("/").slice(-1).join().split(".").shift();
Run Code Online (Sandbox Code Playgroud)

结果将是theName == "filename" ;

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

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

theName = theNameWithExt.split(".").shift();
Run Code Online (Sandbox Code Playgroud)

结果将是theName == "filename",同上;

笔记:

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

但是对于与其他答案的性能比较以及浏览器或操作系统兼容性,我都不能说什么。

工作片段 1:完整路径

theName = thePath.split("/").slice(-1).join().split(".").shift();
Run Code Online (Sandbox Code Playgroud)
theName = theNameWithExt.split(".").shift();
Run Code Online (Sandbox Code Playgroud)

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

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

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

var theNameWithExt = "filename.jpg";
theName = theNameWithExt.split("/").slice(-1).join().split(".").shift();
alert(theName);
Run Code Online (Sandbox Code Playgroud)
  
Run Code Online (Sandbox Code Playgroud)


Cir*_*四事件 5

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

例如/sf/answers/2213099801/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));
Run Code Online (Sandbox Code Playgroud)

输出目录以及:

path/hello
Run Code Online (Sandbox Code Playgroud)

/sf/answers/2526943751/也实现了这一点,但我发现这种方法在语义上更令人愉悦。

在 Node.js v10.15.2 中测试。