32

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?

informatik01
  • 16,038
  • 10
  • 74
  • 104
DCD
  • 1,290
  • 3
  • 12
  • 20
  • http://stackoverflow.com/questions/1302306/how-to-pull-the-file-name-from-a-url-using-javascript-jquery/1302339#1302339 – Gregoire Mar 26 '10 at 19:22
  • ahh cool, I did search but it was probably filename != file name caused me not to find it. – DCD Mar 26 '10 at 19:23

8 Answers8

73
var Filename= path.split('/').pop()
rash
  • 1,316
  • 1
  • 12
  • 17
48
var fileNameIndex = yourstring.lastIndexOf("/") + 1;
var filename = yourstring.substr(fileNameIndex);
Hawkeye Parker
  • 7,817
  • 7
  • 44
  • 47
Gregoire
  • 24,219
  • 6
  • 46
  • 73
8
function getFileName(path) {
return path.match(/[-_\w]+[.][\w]+$/i)[0];
}
makeitmorehuman
  • 11,287
  • 3
  • 52
  • 76
7

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

RubbelDeCatc
  • 747
  • 1
  • 8
  • 10
  • First method will concatenate the complete path to a single string without slashes for windows path. – Manu M Feb 08 '16 at 10:54
  • @ManuM When testing these with string literals you have to use double backslashes in your string like `var win_path = 'c:\\temp\\images\\cat.jpg';`. Otherwise they will not be interpreted as backslashes by JavaScript. – user1404617 Mar 09 '17 at 15:22
  • Sorry I never tested it with windows but maybe the double bs problem with windows path is caused by the three backslashes (\\\) in the regular expression. – RubbelDeCatc May 24 '17 at 07:24
3

In Javascript you could do

function getFileNameFromPath(path) {
  var ary = path.split("/");
  return ary[ary.length - 1];
}
Robusto
  • 31,447
  • 8
  • 56
  • 77
1

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

1

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);
Bullwinkle
  • 11
  • 4
0

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.

Emanuele Scarabattoli
  • 4,103
  • 1
  • 12
  • 21