420

Is there a way that I can get the last value (based on the '\' symbol) from a full path?

Example:

C:\Documents and Settings\img\recycled log.jpg

With this case, I just want to get recycled log.jpg from the full path in JavaScript.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Jin Yong
  • 42,698
  • 72
  • 141
  • 187

22 Answers22

851
var filename = fullPath.replace(/^.*[\\\/]/, '')

This will handle both \ OR / in paths

mikeschuld
  • 943
  • 1
  • 11
  • 25
nickf
  • 537,072
  • 198
  • 649
  • 721
  • 6
    Doesn't work on MAC OSX, using chrome, it escapes character after \ – Pankaj Phartiyal Apr 04 '13 at 07:36
  • 10
    According to this site, using `replace` is *much* slower than `substr`, which can be used in conjunction with `lastIndexOf('/')+1`: http://jsperf.com/replace-vs-substring – Nate Aug 03 '14 at 01:39
  • 1
    @nickf Nick, not sure where I am going wrong but the code doesn't work for me when the file path is having single slash. [`Fiddle`](http://jsfiddle.net/fjxqoz4k/2/), although for [`\\\`](http://jsfiddle.net/fjxqoz4k/4/), it works fine. – Shubh Aug 13 '14 at 10:52
  • @kooky A ``\`` in a JavaScript string **always** creates a character escape, so ``\n`` would insert a new line character, and any unrecognised character escape is changed to the character after the character escape. Therefore, a backwards-slash in a string must be escaped be preceding it with *another* backwards-slash. [Try it out in this JSFiddle](http://jsfiddle.net/fjxqoz4k/5/). You should have noticed that the outputted string doesn't contain **any** backward-slashes. – Toothbrush Aug 13 '14 at 16:15
  • I just wanted to find the relevant part in the string with regex, as Nate showes, but your solution is so brilliant, I have to say thanks to you. You simple delete all the parts before the \ or / chars instead of positioning you in the string. Thanks for your idea, even it is slower than Nate's solution. – jshepherd Sep 22 '14 at 11:43
  • 1
    I just ran this on my console, and it worked perfect for forward slashes: `"/var/drop/foo/boo/moo.js".replace(/^.*[\\\/]/, '')` returns `moo.js` – vikkee Jan 10 '17 at 23:32
  • 2
    Can you explain the regex? – lesolorzanov Feb 06 '17 at 11:21
  • 1
    @ZloySmiertniy There are a couple of good online regex explainers. http://rick.measham.id.au/paste/explain.pl?regex=%2F%5E.*%5B%5C%5C%5C%2F%5D%2F and https://regexper.com/#%2F%5E.*%5B%5C%5C%5C%2F%5D%2F should help. (Links are broken here, but copy-paste into a tab and it'll work) – nickf Feb 06 '17 at 12:07
  • @nickf thanks. It's just that sometimes the expression changes depending the language. Regexper looks awesome! Drawing the expression diagram! :D – lesolorzanov Feb 06 '17 at 12:18
  • 1
    @ZloySmiertniy https://regex101.com/ might also be useful -- you can specify which regex engine you're using. – nickf Feb 06 '17 at 12:19
  • 1
    Unnecessary escape character: \/ no-useless-escape – dude Jul 30 '18 at 15:48
  • Worked in Chrome for me – openwonk Oct 20 '18 at 07:01
  • As @Nate mentioned, replace will be inherently slower because it invokes the regular expression engine, which brings with it enormous power at the expense of performance. Conversely, substring treats the string as an array of characters, which is almost certain to be more efficient than evaluating such a complex regular expression. – David A. Gray Oct 23 '22 at 00:08
195

Just for the sake of performance, I tested all the answers given here:

var substringTest = function (str) {
    return str.substring(str.lastIndexOf('/')+1);
}

var replaceTest = function (str) {
    return str.replace(/^.*(\\|\/|\:)/, '');
}

var execTest = function (str) {
    return /([^\\]+)$/.exec(str)[1];
}

var splitTest = function (str) {
    return str.split('\\').pop().split('/').pop();
}

substringTest took   0.09508600000000023ms
replaceTest   took   0.049203000000000004ms
execTest      took   0.04859899999999939ms
splitTest     took   0.02505500000000005ms

And the winner is the Split and Pop style answer, Thanks to bobince !

Danpe
  • 18,668
  • 21
  • 96
  • 131
  • 7
    Per the meta discussion, please add appropriate citation to other answers. It would also be helpful to better explain how you analyzed the runtime. – jpmc26 Feb 15 '16 at 21:42
  • Feel free to benchmark this version as well. Should support both Mac and Windows file paths. `path.split(/.*[\/|\\]/)[1];` – tim-montague Jul 09 '17 at 03:23
  • 3
    The test is incorrect. substringTest searches only for forward slash, execTest - only for backslash while two remaining handle both slashes. And actual results are not relevant (anymore). Check this out: https://jsperf.com/name-from-path – Grief Aug 14 '18 at 11:23
  • 3
    @Grief that link is no longer valid. – crthompson May 09 '19 at 15:56
177

In Node.js, you can use Path's parse module...

var path = require('path');
var file = '/home/user/dir/file.txt';

var filename = path.parse(file).base;
//=> 'file.txt'
canon
  • 40,609
  • 10
  • 73
  • 97
RobLoach
  • 2,066
  • 1
  • 12
  • 5
92

What platform does the path come from? Windows paths are different from POSIX paths are different from Mac OS 9 paths are different from RISC OS paths are different...

If it's a web app where the filename can come from different platforms there is no one solution. However a reasonable stab is to use both '\' (Windows) and '/' (Linux/Unix/Mac and also an alternative on Windows) as path separators. Here's a non-RegExp version for extra fun:

var leafname= pathname.split('\\').pop().split('/').pop();
bobince
  • 528,062
  • 107
  • 651
  • 834
  • You may want to add that classic MacOS (<= 9) used colon separators (:), but I'm not aware of any browsers that may still be in use that didn't translate MacOS paths to POSIX paths in the form of file:///path/to/file.ext – eyelidlessness Jul 19 '09 at 19:05
  • 4
    You can just use pop() instead of reverse()[0]. It modifies the original array too but it's okay in your case. – Chetan S Jul 19 '09 at 19:10
  • 1
    I'm wondering how we can create a counterpart to get just the path. – Todd Horst Oct 15 '14 at 14:53
  • Something like `var path = '\\Dir2\\Sub1\\SubSub1'; //path = '/Dir2/Sub1/SubSub1'; path = path.split('\\').length > 1 ? path.split('\\').slice(0, -1).join('\\') : path; path = path.split('/').length > 1 ? path.split('/').slice(0, -1).join('/') : path; console.log(path); ` – Todd Horst Oct 15 '14 at 15:00
  • Naming "***leaf***name" is derived from Directory/File structure name "Tree", first thing of *tree* is *root*, the last are the *leaves* => file name is the last thing in the *tree*path => ***leaf*** :-) – jave.web Oct 31 '16 at 10:49
32

Ates, your solution doesn't protect against an empty string as input. In that case, it fails with TypeError: /([^(\\|\/|\:)]+)$/.exec(fullPath) has no properties.

bobince, here's a version of nickf's that handles DOS, POSIX, and HFS path delimiters (and empty strings):

return fullPath.replace(/^.*(\\|\/|\:)/, '');
BlueRaja - Danny Pflughoeft
  • 84,206
  • 33
  • 197
  • 283
user129661
  • 329
  • 3
  • 2
23

The following line of JavaScript code will give you the file name.

var z = location.pathname.substring(location.pathname.lastIndexOf('/')+1);
alert(z);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Epperlyg
  • 247
  • 2
  • 2
15

Another one

var filename = fullPath.split(/[\\\/]/).pop();

Here split have a regular expression with a character class
The two characters have to be escaped with '\'

Or use array to split

var filename = fullPath.split(['/','\\']).pop();

It would be the way to dynamically push more separators into an array, if needed.
If fullPath is explicitly set by a string in your code it need to escape the backslash!
Like "C:\\Documents and Settings\\img\\recycled log.jpg"

  • 1
    Regarding "array to split", I don't see an option to pass an array as a list of delimiters. In fact, the documentation states "If the separator is an array, then that Array is coerced to a String and used as a separator." – mherzog Aug 10 '20 at 19:45
  • `.split(['/','\\'])` is the same as `.split("/,\\")`, which is absolutely not what you want. – Sebastian Simon Apr 04 '21 at 08:17
11

There’s no need to handle backslashes specially; most answers don’t handle search parameters.

The modern approach is to simply use the URL API and get the pathname property. The API normalizes backslashes to slashes. Note that location (in a browser environment) works, too, but only for the current URL, not an arbitrary URL.

In order to parse the resulting %20 to a space, simply pass it to decodeURIComponent.

const getFileName = (fileName) => new URL(fileName).pathname.split("/").pop();

// URLs need to have the scheme portion, e.g. `file://` or `https://`.
console.log(getFileName("file://C:\\Documents and Settings\\img\\recycled log.jpg")); // "recycled%20log.jpg"
console.log(decodeURIComponent(getFileName("file://C:\\Documents and Settings\\img\\recycled log.jpg"))); // "recycled log.jpg"
console.log(getFileName("https://example.com:443/path/to/file.png?size=480")); // "file.png"
.as-console-wrapper { max-height: 100% !important; top: 0; }

Add a .filter(Boolean) before the .pop() if you always want the last non-empty part of the path (e.g. file.png from https://example.com/file.png/).

If you only have a relative URL but still simply want to get the file name, use the second argument of the URL constructor to pass a base origin. "https://example.com" suffices: new URL(fileName, "https://example.com"). It’s also possible to prepend "https://" to your fileName — the URL constructor accepts https://path/to/file.ext as a valid URL.

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
  • I reviewed the URL API for the umpteenth time today, and I still find it wanting because I cannot see anything that it offers that isn't already provided by the built-in location object. – David A. Gray Oct 23 '22 at 03:56
  • @DavidA.Gray E.g. URL validation: `try{ new URL(url); return true; } catch{ return false; }` checks if a URL is valid or not. Not possible with `location`. In this answer, `URL` is not necessarily used for the current URL; I don’t see how to get URI components from an arbitrary URL easily by only using `location` (and without redirecting). Another thing is the search parameter API: there is no `location.searchParams`, but a [`URLSearchParams`](//developer.mozilla.org/en/docs/Web/API/URLSearchParams) object has useful methods. Also, `location` doesn’t exist outside of browsers, but `URL` might. – Sebastian Simon Oct 23 '22 at 09:58
  • @DavidA.Gray Also, from the [specification](//html.spec.whatwg.org/multipage/history.html#the-location-interface): _“Warning: The `Location` exotic object is defined through a mishmash of IDL, invocation of JavaScript internal methods post-creation, and overridden JavaScript internal methods. Coupled with its scary security policy, please take extra care while implementing this excrescence.”_. – Sebastian Simon Oct 23 '22 at 10:38
10

Not more concise than nickf's answer, but this one directly "extracts" the answer instead of replacing unwanted parts with an empty string:

var filename = /([^\\]+)$/.exec(fullPath)[1];
Community
  • 1
  • 1
Ates Goral
  • 137,716
  • 26
  • 137
  • 190
9

A question asking "get file name without extension" refer to here but no solution for that. Here is the solution modified from Bobbie's solution.

var name_without_ext = (file_name.split('\\').pop().split('/').pop().split('.'))[0];
Piyush
  • 3,947
  • 9
  • 36
  • 69
Raymond Sin
  • 101
  • 1
  • 6
9

In Node.js, you can use the path.basename method

const path = require('path');
const file = '/home/user/dir/file.txt';

const filename = path.basename(file);
//=> 'file.txt'
Sam Houston
  • 3,413
  • 2
  • 30
  • 46
4

I use:

var lastPart = path.replace(/\\$/,'').split('\\').pop();

It replaces the last \ so it also works with folders.

pomber
  • 23,132
  • 10
  • 81
  • 94
4

This solution is much simpler and generic, for both 'fileName' and 'path'.

parsePath = (path) => {
    // regex to split path (untile last / or \ to two groups '(.*[\\\/])' for path and '(.*)' (untile the end after the \ or / )for file name
    const regexPath = /^(?<path>(.*[\\\/])?)(?<filename>.*)$/;

    const match = regexPath.exec(path);
    if (path && match) {
        return {
            path: match.groups.path,
            filename: match.groups.filename
        }
    }
    throw Error("Error parsing path");
}

// example
const str = 'C:\\Documents and Settings\\img\\recycled log.jpg';
parsePath(str);

Hicham
  • 766
  • 7
  • 20
  • 1
    The quality of an answer can be improved by adding some explanation to your code. Some folks searching for this answer may be new to coding, or regular expressions, and a little text to give context will go a long way to help understanding. – jmarkmurphy Sep 30 '19 at 17:56
  • 1
    hope this way is better :) – Hicham Oct 01 '19 at 09:38
3

Little function to include in your project to determine the filename from a full path for Windows as well as GNU/Linux & UNIX absolute paths.

/**
 * @param {String} path Absolute path
 * @return {String} File name
 * @todo argument type checking during runtime
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf
 * @example basename('/home/johndoe/github/my-package/webpack.config.js') // "webpack.config.js"
 * @example basename('C:\\Users\\johndoe\\github\\my-package\\webpack.config.js') // "webpack.config.js"
 */
function basename(path) {
  let separator = '/'

  const windowsSeparator = '\\'

  if (path.includes(windowsSeparator)) {
    separator = windowsSeparator
  }

  return path.slice(path.lastIndexOf(separator) + 1)
}
Amin NAIRI
  • 2,292
  • 21
  • 20
2
<script type="text/javascript">
    function test()
    {
        var path = "C:/es/h221.txt";
        var pos =path.lastIndexOf( path.charAt( path.indexOf(":")+1) );
        alert("pos=" + pos );
        var filename = path.substring( pos+1);
        alert( filename );
    }
</script>
<form name="InputForm"
      action="page2.asp"
      method="post">
    <P><input type="button" name="b1" value="test file button"
    onClick="test()">
</form>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

The complete answer is:

<html>
    <head>
        <title>Testing File Upload Inputs</title>
        <script type="text/javascript">

        function replaceAll(txt, replace, with_this) {
            return txt.replace(new RegExp(replace, 'g'),with_this);
        }

        function showSrc() {
            document.getElementById("myframe").href = document.getElementById("myfile").value;
            var theexa = document.getElementById("myframe").href.replace("file:///","");
            var path = document.getElementById("myframe").href.replace("file:///","");
            var correctPath = replaceAll(path,"%20"," ");
            alert(correctPath);
        }
        </script>
    </head>
    <body>
        <form method="get" action="#"  >
            <input type="file"
                   id="myfile"
                   onChange="javascript:showSrc();"
                   size="30">
            <br>
            <a href="#" id="myframe"></a>
        </form>
    </body>
</html>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

A simple function like PHP pathInfo:

function pathInfo(s) {
    s=s.match(/(.*?[\\/:])?(([^\\/:]*?)(\.[^\\/.]+?)?)(?:[?#].*)?$/);
    return {path:s[1],file:s[2],name:s[3],ext:s[4]};
}

console.log( pathInfo('c:\\folder\\file.txt') );

console.log( pathInfo('/folder/another/file.min.js?query=1') );
Type and try it:
<input oninput="document.getElementById('test').textContent=pathInfo(this.value).file" value="c:\folder\folder.name\file.ext" style="width:300px">
MMMahdy-PAPION
  • 915
  • 10
  • 15
0
<html>
    <head>
        <title>Testing File Upload Inputs</title>
        <script type="text/javascript">
            <!--
            function showSrc() {
                document.getElementById("myframe").href = document.getElementById("myfile").value;
                var theexa = document.getElementById("myframe").href.replace("file:///","");
                alert(document.getElementById("myframe").href.replace("file:///",""));
            }
            // -->
        </script>
    </head>
    <body>
        <form method="get" action="#"  >
            <input type="file" 
                   id="myfile" 
                   onChange="javascript:showSrc();" 
                   size="30">
            <br>
            <a href="#" id="myframe"></a>
        </form>
    </body>
</html>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Ferrybig Feb 12 '16 at 15:13
0

Successfully Script for your question ,Full Test

<script src="~/Scripts/jquery-1.10.2.min.js"></script>

<p  title="text" id="FileNameShow" ></p>
<input type="file"
   id="myfile"
   onchange="javascript:showSrc();"
   size="30">


<script type="text/javascript">

function replaceAll(txt, replace, with_this) {
    return txt.replace(new RegExp(replace, 'g'), with_this);
}

function showSrc() {
    document.getElementById("myframe").href = document.getElementById("myfile").value;
    var theexa = document.getElementById("myframe").href.replace("file:///", "");
    var path = document.getElementById("myframe").href.replace("file:///", "");
    var correctPath = replaceAll(path, "%20", " ");
   alert(correctPath);
    var filename = correctPath.replace(/^.*[\\\/]/, '')
    $("#FileNameShow").text(filename)
}

Amin Saadati
  • 719
  • 8
  • 21
0

Replace is slower use substring

var fileName = fullPath.substring(fullPath.lastIndexOf('\\')+1);

Note: If you want to get from input field than you can directly get by the bellow simple code if any file is selected. Assume id="file"

var fileName = document.getElementById('file').files[0].name;
MD TAREK HOSSEN
  • 129
  • 2
  • 11
-3

var file_name = file_path.substring(file_path.lastIndexOf('/'));

T J
  • 42,762
  • 13
  • 83
  • 138
shriniket
  • 55
  • 1
  • 7
-3
function getFileName(path, isExtension){

  var fullFileName, fileNameWithoutExtension;

  // replace \ to /
  while( path.indexOf("\\") !== -1 ){
    path = path.replace("\\", "/");
  }

  fullFileName = path.split("/").pop();
  return (isExtension) ? fullFileName : fullFileName.slice( 0, fullFileName.lastIndexOf(".") );
}
Marek Woźniak
  • 1,766
  • 16
  • 34
Tomas
  • 1,377
  • 3
  • 17
  • 32