使用JavaScript从路径获取文件名

32

我有一个图片的完整路径,我正在使用jQuery读取它,像这样:

$('img.my_image').attr('src');

然而我只想要文件名部分(即不包括完整路径)。

是否有内置函数可以做到这一点,或者只能使用正则表达式


https://dev59.com/0XM_5IYBdhLWcg3wn0hO#1302339 - Gregoire
啊,太酷了,我确实搜索过,但可能是因为文件名不等于文件名,所以我没有找到它。 - DCD
8个回答

75
var Filename= path.split('/').pop()

2
在我看来,这比被接受的答案更好。 - M -
1
我认为应该是这样的var Filename=path.split('\').pop(); 它测试了上述代码,但在IE和智能手机上无法工作。 - Moe
1
@Moe 路径分隔符在不同平台上有所不同。 - Lightness Races in Orbit
最佳答案!跨平台兼容性 - Nicky Kouffeld

48
var fileNameIndex = yourstring.lastIndexOf("/") + 1;
var filename = yourstring.substr(fileNameIndex);

4
不适用于Linux和Mac,您需要使用斜杠(\和/)来分隔。 - RubbelDeCatc
1
RubbelDeCatc的下面的答案对于需要跨平台解决方案的正斜杠和反斜杠都很有效。 - user1404617

8
function getFileName(path) {
return path.match(/[-_\w]+[.][\w]+$/i)[0];
}

7

我发现一个更好的处理类Unix和类Windows路径字符串的版本。

第一点:

var unix_path = '/tmp/images/cat.jpg';
console.log(unix_path.replace(/^.*[\\\/]/, ''));

var win_path = 'c:\\temp\images\cat.jpg';
console.log(win_path.replace(/^.*[\\\/]/, ''));

输出结果将会是cat.jpg

第二个方法:(可能更快)

var unix_path = '/tmp/images/cat.jpg';
console.log(unix_path.split(/[\\\/]/).pop());

var win_path = 'c:\\temp\images\cat.jpg';
console.log(win_path.split(/[\\\/]/).pop());

输出结果将是cat.jpg

第一种方法将完整路径连接成一个字符串,不包含斜杠以适用于Windows路径。 - Manu M
@ManuM 当你使用字符串字面量进行测试时,必须在字符串中使用双反斜杠,例如 var win_path = 'c:\\temp\\images\\cat.jpg';。否则,JavaScript 将无法将其解释为反斜杠。 - user1404617
抱歉,我从未在Windows上测试过它,但也许与Windows路径的双反斜杠问题有关的是正则表达式中的三个反斜杠(\\)。 - RubbelDeCatc

3
在JavaScript中,您可以这样做:
function getFileNameFromPath(path) {
  var ary = path.split("/");
  return ary[ary.length - 1];
}

1
使用此解决方案,您可以获得包括文件扩展名和不包括文件扩展名在内的两个名称。
    //获取图像源
    var path=$('img.my_image').attr('src');
//分割URL并获取带有文件扩展名的文件名 var file=path.split('/').pop();
//删除扩展名,只保留文件名 var filename=file.split('.').shift();

1

除了已接受的答案外,这似乎是最快速且跨平台(Unix和Windows)的解决方案:

function basePath(path) {
  return path.substr(
    Math.max(
      path.lastIndexOf('\\'),
      path.lastIndexOf('/'),
    ) + 1,
  );
}

当你有来自Unix和Windows的数据需要在一个地方解析时,这是必要的。

该函数只取所有可能分隔符的最新值,并返回最后一个分隔符后的字符串。对于大字符串,它比较快,原因如下:

  • 没有正则表达式,它们比简单的相等性慢
  • 没有规范化,没有无条件地遍历整个字符串并从中创建新内容
  • 没有创建任何新实例,例如新数组等,这需要一些时间和内存
  • 没有额外的循环或查找,因为我们不在这里使用数组

Tested in Chromex87:

// Test subjects
//=====================
function basePathUnix(path) {
  return path.split('/').pop();
}

function basePathUnix2(path) {
  const arr = path.split('/');
  return arr[ arr.length - 1 ];
}

function basePathUnix3(path) {
  return path.substr(path.lastIndexOf('/') + 1);
}

function basePathCrossPlatform(path) {
  return path.replace(/^.*[\\\/]/, '');
}

function basePathCrossPlatform2(path) {
  return path.split(/[\\\/]/).pop();
}

function basePathCrossPlatform3(path) {
  return path.substr(Math.max(path.lastIndexOf('\\'), path.lastIndexOf('/')) + 1);
}

function basePathCrossPlatform4(path, separators = ['/', '\\']) {
  return path.substr(Math.max(...separators.map(s => path.lastIndexOf(s))) + 1);
}

// Tests
//=====================
function measureTime(name, fn) {
  const start = window.performance.now();
  for (let i = 0; i < 10000; i++) {
    fn();
  }
  const time = window.performance.now() - start;

  console.log(name, time);
}

function testResults(name, path) {
  console.log('\n[CHECK RESULTS]', name);

  console.log('basePathUnix:\t\t', basePathUnix(path));
  console.log('basePathUnix2:\t\t', basePathUnix2(path));
  console.log('basePathUnix3:\t\t', basePathUnix3(path));
  console.log('basePathCrossPlatform:\t', basePathCrossPlatform(path));
  console.log('basePathCrossPlatform2:\t', basePathCrossPlatform2(path));
  console.log('basePathCrossPlatform3:\t', basePathCrossPlatform3(path));
  console.log('basePathCrossPlatform4:\t', basePathCrossPlatform4(path));
}

function testPerformance(name, path) {
  console.log('\n[MEASURE PERFORMANCE]', name);

  measureTime('basePathUnix:\t\t', () => basePathUnix(path));
  measureTime('basePathUnix2:\t\t', () => basePathUnix2(path));
  measureTime('basePathUnix3:\t\t', () => basePathUnix3(path));
  measureTime('basePathCrossPlatform:\t', () => basePathCrossPlatform(path));
  measureTime('basePathCrossPlatform2:\t', () => basePathCrossPlatform2(path));
  measureTime('basePathCrossPlatform3:\t', () => basePathCrossPlatform3(path));
  measureTime('basePathCrossPlatform4:\t', () => basePathCrossPlatform4(path));
}

function runTest(name, path) {
  setTimeout(() => {
    testResults(name, path);

    setTimeout(() => {
      testPerformance(name, path);
    }, 200);
  }, 200);
}

// Run tests
//=====================
setTimeout(() => {
  const pathUnix = '/some/path/string/some/path/string/some/path/string/some/path/string/some/path/string/some/path/file-name';
  runTest('UNIX', pathUnix);
}, 1000);

setTimeout(() => {
  const pathWind = '\\some\\path\\string\\some\\path\\string\\some\\path\\string\\some\\path\\string\\some\\path\\file-name';
  runTest('WINDOWS', pathWind);
}, 2000);


0
如果您想同时包含“/”和“\”路径分隔符,我建议使用以下方式:
const getFileName = filePath => filePath.replaceAll("\\", "/").split("/").pop();

getFileName("/a/b/c.txt");
// It will return "c.txt"

getFileName("\\a\\b\\c.txt"); // The "\\" is just to escape "\" char
// It will still return "c.txt"

这将支持Windows和非Windows操作系统。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接