Javascript-如何从文件输入控件中提取文件名


117

当用户在网页中选择文件时,我希望能够仅提取文件名。

我确实尝试过str.search函数,但是当文件名像这样时似乎失败:c:\ uploads \ ilike.this.file.jpg

我们如何仅提取不带扩展名的文件名?

Answers:


127

假设您的<input type =“ file”>具有上 ID,则有望实现此目的:

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

谢谢,这似乎工作得很好,但我只想要不带扩展名的文件名。我该如何在上面的代码中做到这一点。
Yogi Yang 007,2009年

我添加了这两行代码以仅提取不带扩展名的文件名:“ filename = filename.substring(0,filename.length-4); filename = filename.toLowerCase();”
Yogi Yang 007,2009年

13
不,您不想那样做,Yogi Yang说。而是使用:filename = filename.substring(0, filename.lastIndexOf('.'));因为他的方式将与多个字符的扩展比3,从而失败:html的,.JPEG等
雪人

1
在选择多个文件的情况下如何获取文件名?
avngr

为什么不像这样计算startIndex?var startIndex = Math.max(fullPath.lastIndexOf('\\'), fullPath.lastIndexOf('/')) + 1;
nollidge

196

要分割字符串({filepath} / {filename})并获取文件名,您可以使用以下命令:

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

“ pop方法从数组中删除最后一个元素,并将该值返回给调用者。”
Mozilla开发人员网络

例:

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

你得到: "file.txt"


5
您也可以只使用正则表达式而无需任何数组操作即可:var filename = filepath.replace(/^.*?([^\\\/]*)$/, '$1');
vog 2015年

1
vog的答案确实非常接近问题的100%准确答案(除了需要删除扩展名。)文件名与任何其他字符串都没有不同。
乔恩·瓦特

1
分割正则表达式可以缩短为[\\/]。此外,也有人要求剥离文件扩展名。有关完整的解决方案,请参阅:stackoverflow.com/a/32156800/19163
vog

多平台,简洁。大。
Marc'5

好的解决方案,我不知道它是如何工作的,这就是为什么更喜欢它!
Chatoxz

92

如今,有一种更简单的方法:

var fileInput = document.getElementById('upload');   
var filename = fileInput.files[0].name;

5
如果用户单击“取消”,请fileInput.files.length在致电之前进行检查.name
marcovtwout

29

很简单

let file = $("#fileupload")[0].files[0]; 
file.name

如果您使用的是TypeScript,则其$(“#fileupload”)[0] [“ files”] [0];
Morvael

18

假设:

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

JavaScript将是:

var fileName = document.getElementById('theFile').files[0].name;

8
var pieces = str.split('\\');
var filename = pieces[pieces.length-1];

这假定用户正在运行Windows。其他操作系统使用不同的文件路径分隔符。
昆丁

您是否还需要为非Windows用户检查'/'字符,例如,如果(!pieces){str.split('/'); }?不错的简单解决方案,但+1
Ian Oxley

IIRC,IE是唯一提供文件完整路径的浏览器...您无需在Firefox之类的其他浏览器上进行拆分,因此它仍然可以工作。尽管我承认我还没有尝试过所有linux / unix浏览器。
TM。

6
str.split(/(\\ | \ /)/ g); Windows和* nix
Tracker1,2009年

@TM值。Chrome使用伪造的路径变量来提高安全性,这很丑陋;iirc取决于您所使用的操作系统。
lededje 2013年

5

我假设您要剥离所有扩展名,即/tmp/test/somefile.tar.gzto somefile

正则表达式的直接方法:

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

正则表达式和数组操作的替代方法:

var filename = filepath.split(/[\\/]/g).pop().split('.')[0];

1
并不会按照要求删除扩展名。
乔恩·瓦特

固定。感谢您的提示!
vog

4

我刚刚制作了自己的版本。我的函数可用于从中提取所需的任何内容,如果不需要全部,则可以轻松删除一些代码。

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

将输出以下内容:

  • 名称为“ testcase1”的文件具有扩展名:“ jpeg”在目录中:“ C:\ blabla \ blaeobuaeu”
  • 名称为“ testcase2”的文件具有扩展名:“ png”在目录中:“ / tmp / blabla”
  • 名称为'testcase3'的文件具有扩展名:'htm'在目录中:''
  • 名称为“ Testcase4”的目录具有扩展名:“”位于目录:“ C:”中
  • 名称为“ fileWithoutDots”的目录具有扩展名:“”位于目录:“ / dir.with.dots”中
  • 名称为“”的目录具有扩展名:“”位于目录:“ / dir.with.dots / another.dir”

随着&& nOffset+1 === str.length加入到isDirectory

  • 名称为“ testcase1”的文件具有扩展名:“ jpeg”在目录中:“ C:\ blabla \ blaeobuaeu”
  • 名称为“ testcase2”的文件具有扩展名:“ png”在目录中:“ / tmp / blabla”
  • 名称为'testcase3'的文件具有扩展名:'htm'在目录中:''
  • 名称为“ Testcase4”的目录具有扩展名:“”位于目录:“ C:”中
  • 名称为“ fileWithoutDots”的目录具有扩展名:“”位于目录:“ / dir.with.dots”中
  • 名称为“”的目录具有扩展名:“”位于目录:“ / dir.with.dots / another.dir”

在给出测试用例的情况下,您可以看到此功能与此处提出的其他方法相比非常健壮。

对于新手,请注意\\:\是转义字符,例如\ n表示换行符和\ ta选项卡。为了能够编写\ n,您必须实际键入\\ n。


1
请注意以下路径:dir.with.dots / fileWithoutDots,因为您得到的eOffset小于nOffset并混淆了提取表达式。
Jesse Chisholm

是的,修复它。现在,它也应该正常工作(添加了&& eOffset < nOffset)。
雪人

2

输入C:\path\Filename.ext
输出Filename

在HTML代码中,onChange像这样设置File 值...

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

假设您的文本字段ID为“ 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>

1

没有一个被高度评价的答案实际上没有提供“只是文件名而没有扩展名”,而其他解决方案对于这种简单的工作来说却是太多的代码。

我认为这应该是任何JavaScript程序员的单线。这是一个非常简单的正则表达式:

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

首先,将所有内容剥离到最后一个斜杠(如果存在)。

然后,在最后一个周期之后删除所有内容(如果有)。

它很简单,很健壮,可以准确地实现所需的功能。我想念什么吗?


1
“一个非常简单的正则表达式”……嗯,实际上这是两个正则表达式。:-)有关单正则表达式的解决方案,请参见我的回答。
vog

是的,还有明显的重写,可以使用管道(|)运算符将这两个正则表达式打包为一个正则表达式。我认为编写的代码更清晰,但是它确实在字符串中运行了两次,如果字符串通常很长,那将是一个问题。(文件路径通常不是,但是可以。)
Jon Watte

1
我只是在挑剔。请不要认真对待。无需优化,所有提出的解决方案都足够快。非常长的文件路径仍然是千字节,而不是千兆字节。并且此功能将在每次上传文件时触发一次,而不是批量触发1000次。这里唯一重要的是代码的正确性和清晰度。
vog

1
// 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
}

如何删除扩展名


1
这遗漏了问题的重要部分,“仅提取文件名而不扩展名”。在跳出来回答问题之前,先仔细阅读问题会有所帮助。
zeh

1
var path = document.getElementById('upload').value;//take path
var tokens= path.split('\\');//split path
var filename = tokens[tokens.length-1];//take file name

0

上面的答案都不对我有用,这是我的解决方案,它使用文件名更新禁用的输入:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.