163

When a user selects a file in a web page I want to be able to extract just the filename.

I did try str.search function but it seems to fail when the file name is something like this: c:\uploads\ilike.this.file.jpg.

How can we extract just the file name without extension?

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
Yogi Yang 007
  • 5,147
  • 10
  • 56
  • 77

15 Answers15

248

To split the string ({filepath}/{filename}) and get the file name you could use something like this:

str.split(/(\\|\/)/g).pop()

"The pop method removes the last element from an array and returns that value to the caller."
Mozilla Developer Network

Example:

from: "/home/user/file.txt".split(/(\\|\/)/g).pop()

you get: "file.txt"

Joe DF
  • 5,438
  • 6
  • 41
  • 63
VallaDanger
  • 2,579
  • 2
  • 13
  • 7
  • 9
    You can also do that just with regexes and without any array operation: `var filename = filepath.replace(/^.*?([^\\\/]*)$/, '$1');` – vog Aug 22 '15 at 13:43
  • 1
    vog's answer is really close to the 100% accurate answer to the question (except needs to strip the extension.) A filename is no different from any other string. – Jon Watte May 21 '16 at 19:38
  • 2
    The split regex can be shortened to `[\\/]`. Moreover, it was asked for stripping the file extension, too. For a complete solution, see: http://stackoverflow.com/a/32156800/19163 – vog Sep 09 '16 at 16:16
  • I think the 'longer' regex version of `(\\|\/)` (vs the short `[\\/]`) handles different path name syntax on different OSs, no? Its `C:\path\Filename.ext`on Windows, and `home/path/Filename.ext`on linux and macOs? – wnm Dec 16 '21 at 09:44
171

Nowadays there is a much simpler way:

var fileInput = document.getElementById('upload');   
var filename = fileInput.files[0].name;
maxime schoeni
  • 2,666
  • 2
  • 18
  • 19
149

Assuming your <input type="file" > has an id of upload this should hopefully do the trick:

var fullPath = document.getElementById('upload').value;
if (fullPath) {
    var startIndex = (fullPath.indexOf('\\') >= 0 ? fullPath.lastIndexOf('\\') : fullPath.lastIndexOf('/'));
    var filename = fullPath.substring(startIndex);
    if (filename.indexOf('\\') === 0 || filename.indexOf('/') === 0) {
        filename = filename.substring(1);
    }
    alert(filename);
}
Sebas
  • 21,192
  • 9
  • 55
  • 109
Ian Oxley
  • 10,916
  • 6
  • 42
  • 49
  • Thanks this seems to work well, but I just want filename without extension. How can I do that in above code. – Yogi Yang 007 May 13 '09 at 12:35
  • I added these two lines of code to extract just the file name without extension: "filename = filename.substring(0,filename.length-4); filename = filename.toLowerCase();" – Yogi Yang 007 May 13 '09 at 12:56
  • 14
    Nope, you don't want to do it that way Yogi Yang says. Instead use: `filename = filename.substring(0, filename.lastIndexOf('.'));` Because his way will fail with extensions of more characters than 3, thus: .html, .jpeg etc. – Yeti May 10 '12 at 16:02
  • 1
    how to get the filenames in case of multiple file selection? – avngr May 02 '15 at 16:07
  • Why not just calculate startIndex like so? `var startIndex = Math.max(fullPath.lastIndexOf('\\'), fullPath.lastIndexOf('/')) + 1;` – nollidge Dec 15 '15 at 17:17
45

Very simple

let file = $("#fileupload")[0].files[0]; 
file.name
Uchenna
  • 4,059
  • 6
  • 40
  • 73
29

Assuming:

<input type="file" name="file1" id="theFile">

The JavaScript would be:

var fileName = document.getElementById('theFile').files[0].name;
Xedret
  • 1,823
  • 18
  • 25
9

I assume you want to strip all extensions, i.e. /tmp/test/somefile.tar.gz to somefile.

Direct approach with regex:

var filename = filepath.match(/^.*?([^\\/.]*)[^\\/]*$/)[1];

Alternative approach with regex and array operation:

var filename = filepath.split(/[\\/]/g).pop().split('.')[0];
vog
  • 23,517
  • 11
  • 59
  • 75
8
var pieces = str.split('\\');
var filename = pieces[pieces.length-1];
TM.
  • 108,298
  • 33
  • 122
  • 127
  • This assumes that the user is running Windows. Other operating systems use different file path seperators. – Quentin May 13 '09 at 12:26
  • Would you need to check for the '/' character as well for non-Windows users e.g. if (!pieces) { str.split('/'); }? Nice simple solution though +1 – Ian Oxley May 13 '09 at 12:27
  • IIRC, IE is the only browser that gives the full path of the file anyway... You won't need to split on other browsers like Firefox, so it still works. Although I admit I haven't tried EVERY linux/unix browser. – TM. May 13 '09 at 12:29
  • 7
    str.split(/(\\|\/)/g); for windows and *nix – Tracker1 May 14 '09 at 08:22
  • @TM. Chrome uses a fake path variable for safety which is ugly; iirc it is different depending on what OS you are on. – lededje Jan 07 '13 at 12:34
  • Oddly enough, it is only the Windows user interface and compilers that care whether you use "\" or "/" for directory separator. The internal Win32 and kernel libraries treat them the same. – Jesse Chisholm Mar 23 '14 at 21:47
6

Input: C:\path\Filename.ext
Output: Filename

In HTML code, set the File onChange value like this...

<input type="file" name="formdata" id="formdata" onchange="setfilename(this.value)"/>

Assuming your textfield id is 'wpName'...

<input type="text" name="wpName" id="wpName">

JavaScript

<script>
  function setfilename(val)
  {
    filename = val.split('\\').pop().split('/').pop();
    filename = filename.substring(0, filename.lastIndexOf('.'));
    document.getElementById('wpName').value = filename;
  }
</script>
DxTx
  • 3,049
  • 3
  • 23
  • 34
5

I just made my own version of this. My function can be used to extract whatever you want from it, if you don't need all of it, then you can easily remove some code.

<html>
<body>
<script type="text/javascript">
// Useful function to separate path name and extension from full path string
function pathToFile(str)
{
    var nOffset = Math.max(0, Math.max(str.lastIndexOf('\\'), str.lastIndexOf('/')));
    var eOffset = str.lastIndexOf('.');
    if(eOffset < 0 && eOffset < nOffset)
    {
        eOffset = str.length;
    }
    return {isDirectory: eOffset === str.length, // Optionally: && nOffset+1 === str.length if trailing slash means dir, and otherwise always file
            path: str.substring(0, nOffset),
            name: str.substring(nOffset > 0 ? nOffset + 1 : nOffset, eOffset),
            extension: str.substring(eOffset > 0 ? eOffset + 1 : eOffset, str.length)};
}

// Testing the function
var testcases = [
    "C:\\blabla\\blaeobuaeu\\testcase1.jpeg",
    "/tmp/blabla/testcase2.png",
    "testcase3.htm",
    "C:\\Testcase4", "/dir.with.dots/fileWithoutDots",
    "/dir.with.dots/another.dir/"
];
for(var i=0;i<testcases.length;i++)
{
    var file = pathToFile(testcases[i]);
    document.write("- " + (file.isDirectory ? "Directory" : "File") + " with name '" + file.name + "' has extension: '" + file.extension + "' is in directory: '" + file.path + "'<br />");
}
</script>
</body>
</html>

Will output the following:

  • File with name 'testcase1' has extension: 'jpeg' is in directory: 'C:\blabla\blaeobuaeu'
  • File with name 'testcase2' has extension: 'png' is in directory: '/tmp/blabla'
  • File with name 'testcase3' has extension: 'htm' is in directory: ''
  • Directory with name 'Testcase4' has extension: '' is in directory: 'C:'
  • Directory with name 'fileWithoutDots' has extension: '' is in directory: '/dir.with.dots'
  • Directory with name '' has extension: '' is in directory: '/dir.with.dots/another.dir'

With && nOffset+1 === str.length added to isDirectory:

  • File with name 'testcase1' has extension: 'jpeg' is in directory: 'C:\blabla\blaeobuaeu'
  • File with name 'testcase2' has extension: 'png' is in directory: '/tmp/blabla'
  • File with name 'testcase3' has extension: 'htm' is in directory: ''
  • Directory with name 'Testcase4' has extension: '' is in directory: 'C:'
  • Directory with name 'fileWithoutDots' has extension: '' is in directory: '/dir.with.dots'
  • Directory with name '' has extension: '' is in directory: '/dir.with.dots/another.dir'

Given the testcases you can see this function works quite robustly compared to the other proposed methods here.

Note for newbies about the \\: \ is an escape character, for example \n means a newline and \t a tab. To make it possible to write \n, you must actually type \\n.

Yeti
  • 2,647
  • 2
  • 33
  • 37
  • 1
    Watch out for this path: **dir.with.dots/fileWithoutDots** as you will get eOffset less than nOffset and confuse the extraction expressions. – Jesse Chisholm Mar 23 '14 at 21:49
  • Yeah, fixed it. Now that should work properly too (added `&& eOffset < nOffset`). – Yeti Dec 04 '16 at 13:23
3

Neither of the highly upvoted answers actually provide "just the file name without extension" and the other solutions are way too much code for such a simple job.

I think this should be a one-liner to any JavaScript programmer. It's a very simple regular expression:

function basename(prevname) {
    return prevname.replace(/^(.*[/\\])?/, '').replace(/(\.[^.]*)$/, '');
}

First, strip anything up to the last slash, if present.

Then, strip anything after the last period, if present.

It's simple, it's robust, it implements exactly what's asked for. Am I missing something?

Jon Watte
  • 6,579
  • 4
  • 53
  • 63
  • 1
    "a very simple regular expression" ... Well, actually these are two regexes. :-) See my answer for a single-regex solution. – vog Sep 09 '16 at 16:14
  • Yes, there is also an obvious re-write to pack those two regexes into a single regex using the pipe (|) operator. I think the code as written is clearer, but it does run through the string twice, which would be a problem if the string is generally pretty long. (File paths typically aren't, but can be.) – Jon Watte Sep 10 '16 at 17:57
  • 1
    I was just nitpicking. Please don't take that seriously. There is no need to optimize, all proposed solutions are more than fast enough. Very long file paths are still kilobytes, not gigabytes. And this function will be triggered once per file upload, not 1000x in a batch. The only things that matter here are correctness and clarity of the code. – vog Sep 14 '16 at 07:11
3

Easy Path:

JQuery

$("#fileInputId").on("change", () => {
    alert($("#fileInputId")[0].files[0].name);
});

JavaScript

document.getElementById("fileInputId").onchange = function() {
   alert(document.getElementById("fileInputId").files[0].name)
};
Saeid
  • 422
  • 4
  • 9
2
// HTML
<input type="file" onchange="getFileName(this)">

// JS
function getFileName(input) {
    console.log(input.files[0].name) // With extension
    console.log(input.files[0].name.replace(/\.[^/.]+$/, '')) // Without extension
}

How to remove the extension

Mikel
  • 5,902
  • 5
  • 34
  • 49
  • 1
    This misses an important part of the question, "extract just the file name without extension". It helps to read the question carefully first before jumping to answer it. – zeh Mar 07 '18 at 14:22
1
var path = document.getElementById('upload').value;//take path
var tokens= path.split('\\');//split path
var filename = tokens[tokens.length-1];//take file name
Luca C.
  • 11,714
  • 1
  • 86
  • 77
0

None of the above answers worked for me, here is my solution which updates a disabled input with the filename:

<script type="text/javascript"> 
  document.getElementById('img_name').onchange = function () {
  var filePath = this.value;
    if (filePath) {
      var fileName = filePath.replace(/^.*?([^\\\/]*)$/, '$1');
      document.getElementById('img_name_input').value = fileName;
    }
  };
</script>
sigi
  • 189
  • 3
  • 9
-3

If you are using jQuery then

$("#fileupload").val();
Rajat Bansal
  • 885
  • 9
  • 7