DCD
DCD

Reputation: 1290

Getting just the filename from a path with JavaScript

I have a full path to an image, which I am using jQuery to read like this:

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

However I just want the filename portion (i.e. without full path).

Are there any built-in functions to do this, or would a regex be the only option?

Upvotes: 32

Views: 70386

Answers (8)

Emanuele Scarabattoli
Emanuele Scarabattoli

Reputation: 4489

If you want to include both "/" and "\" path separators, I would suggest:

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"

This will support Windows and non-Windows OSs.

Upvotes: 0

Bullwinkle
Bullwinkle

Reputation: 11

Addition to accepted answer. Looks like here is fastest and cross platform (Unix and Windows) solution:

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

It's necessary in situation, when you have data from both Unix and Windows and we have to parse in in one place.

This function just takes latest of all possible separators and returns string after last separator. It is much faster with big strings and that's why:

  • no regexps, they are slower then simple equality
  • no normalization, have no unconditionally go threw whole the string and make something new from it
  • no creating any new instances, like new arrays and so on, it takes some time and memory
  • no extra cycles or even lookups because we don't use arrays here

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

Upvotes: 1

The Bad Brad
The Bad Brad

Reputation: 11

Using this solution you can get both names i.e. with and without file extension.


    //getting image source
    var path=$('img.my_image').attr('src');

    //splitting url and getting filename with file extension
    var file=path.split('/').pop();

    //removing extension and keeping just the filename
    var filename=file.split('.').shift();

Upvotes: 1

RubbelDeCatc
RubbelDeCatc

Reputation: 765

I found a better version handling unix and windows-like path-strings.

Number 1:

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(/^.*[\\\/]/, ''));

Output will be cat.jpg

Number 2: (maybe faster)

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());

Output will be cat.jpg

Upvotes: 7

rash
rash

Reputation: 1354

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

Upvotes: 76

Gregoire
Gregoire

Reputation: 24882

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

Upvotes: 48

Robusto
Robusto

Reputation: 31913

In Javascript you could do

function getFileNameFromPath(path) {
  var ary = path.split("/");
  return ary[ary.length - 1];
}

Upvotes: 3

Ali Habibzadeh
Ali Habibzadeh

Reputation: 11577

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

Upvotes: 8

Related Questions