【问题标题】:Javascript - How to extract filename from a file input controlJavascript - 如何从文件输入控件中提取文件名
【发布时间】:2010-10-25 20:24:20
【问题描述】:

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

我确实尝试了 str.search 功能,但是当文件名如下时它似乎失败了:c:\uploads\ilike.this.file.jpg

我们怎样才能只提取没有扩展名的文件名?

【问题讨论】:

    标签: javascript browser extract


    【解决方案1】:
    var pieces = str.split('\\');
    var filename = pieces[pieces.length-1];
    

    【讨论】:

    • 这假定用户正在运行 Windows。其他操作系统使用不同的文件路径分隔符。
    • 您是否还需要为非 Windows 用户检查“/”字符,例如if (!pieces) { str.split('/'); }?不错的简单解决方案 +1
    • IIRC,IE 是唯一提供文件完整路径的浏览器...您无需在 Firefox 等其他浏览器上进行拆分,因此它仍然有效。虽然我承认我没有尝试过每一个 linux/unix 浏览器。
    • str.split(/(\\|\/)/g);对于 windows 和 *nix
    • @TM。为了安全起见,Chrome 使用了一个虚假的路径变量,这很丑陋; iirc 根据您使用的操作系统而有所不同。
    【解决方案2】:

    假设您的 的 id 为 upload,这应该可以解决问题:

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

    【讨论】:

    • 谢谢,这似乎运作良好,但我只想要不带扩展名的文件名。我怎样才能在上面的代码中做到这一点。
    • 我添加了这两行代码来只提取不带扩展名的文件名:“filename = filename.substring(0,filename.length-4); filename = filename.toLowerCase();”
    • 不,你不想按照 Yogi Yang 所说的那样做。而是使用:filename = filename.substring(0, filename.lastIndexOf('.')); 因为他的方式将失败,因为扩展名超过 3 个字符,因此:.html、.jpeg 等。
    • 多选文件如何获取文件名?
    • 为什么不直接计算 startIndex 呢? var startIndex = Math.max(fullPath.lastIndexOf('\\'), fullPath.lastIndexOf('/')) + 1;
    【解决方案3】:

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

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

    "pop 方法从数组中删除最后一个元素并返回 对调用者的价值。”
    Mozilla Developer Network

    例子:

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

    你得到:"file.txt"

    【讨论】:

    • 您也可以只使用正则表达式而不需要任何数组操作:var filename = filepath.replace(/^.*?([^\\\/]*)$/, '$1');
    • vog 的答案非常接近问题的 100% 准确答案(除了需要去掉扩展名。)文件名与任何其他字符串没有什么不同。
    • 拆分正则表达式可以缩短为[\\/]。此外,它也被要求剥离文件扩展名。如需完整的解决方案,请参阅:stackoverflow.com/a/32156800/19163
    • 多平台,简洁。太好了。
    • 很好的解决方案,我不明白它是如何工作的,这就是为什么更喜欢它!
    【解决方案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”

    &amp;&amp; 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 表示换行符,\t 表示制表符。为了能够写 \n,您必须实际输入 \\n。

    【讨论】:

    • 注意这条路径:dir.with.dots/fileWithoutDots,因为你会得到小于 nOffset 的 eOffset 并混淆提取表达式。
    • 是的,已修复。现在它也应该可以正常工作了(添加了&amp;&amp; eOffset &lt; nOffset)。
    【解决方案5】:

    我假设您想删除所有扩展名,即 /tmp/test/somefile.tar.gzsomefile

    使用正则表达式的直接方法:

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

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

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

    【讨论】:

    • 这不会按要求剥离扩展名。
    • 已修复。感谢您的提示!
    【解决方案6】:

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

    我认为这对任何 JavaScript 程序员来说都应该是一个单行字。这是一个非常简单的正则表达式:

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

    首先,删除任何内容,直到最后一个斜线(如果存在)。

    然后,删除最后一个句号之后的任何内容(如果存在)。

    它很简单,它很健壮,它完全实现了所要求的。我错过了什么吗?

    【讨论】:

    • "一个非常简单的正则表达式" ...嗯,实际上这是两个正则表达式。 :-) 请参阅我对单一正则表达式解决方案的回答。
    • 是的,还有一个明显的重写是使用管道 (|) 运算符将这两个正则表达式打包成一个正则表达式。我认为编写的代码更清晰,但它确实遍历了字符串两次,如果字符串通常很长,这将是一个问题。 (文件路径通常不是,但可以是。)
    • 我只是在吹毛求疵。请不要认真对待。无需优化,所有提出的解决方案都足够快。非常长的文件路径仍然是千字节,而不是千兆字节。而且这个功能每次上传文件都会触发一次,而不是批量1000x。这里唯一重要的是代码的正确性和清晰度。
    【解决方案7】:

    现在有一个更简单的方法:

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

    【讨论】:

    • 在调用.name之前检查fileInput.files.length,以防用户点击取消。
    【解决方案8】:

    很简单

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

    【讨论】:

    • 如果您使用的是 TypeScript,那么它的 $("#fileupload")[0]["files"][0];
    【解决方案9】:

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

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

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

    【讨论】:

      【解决方案10】:

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

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

      【讨论】:

        【解决方案11】:

        如果你使用的是 jQuery,那么

        $("#fileupload").val();
        

        【讨论】:

        • val() 实际上会返回他不想要的整个文件路径。
        【解决方案12】:
        // 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

        【讨论】:

        • 这错过了问题的一个重要部分,“仅提取文件名而不提取扩展名”。在开始回答之前先仔细阅读问题会有所帮助。
        【解决方案13】:

        假设:

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

        JavaScript 将是:

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

        【讨论】:

          【解决方案14】:
          var path = document.getElementById('upload').value;//take path
          var tokens= path.split('\\');//split path
          var filename = tokens[tokens.length-1];//take file name
          

          【讨论】:

            【解决方案15】:
            //x=address or src
            if(x.includes('/')==true){xp=x.split('/')} //split address
            if(x.includes('\\')==true){xp=x.split('\\')} //split address
            xl=xp.length*1-1;xn=xp[xl] //file==xn
            xo=xn.split('.'); //file parts=xo
            if(xo.lenght>2){xol=xo.length-1;xt=xo[xol];xr=xo.splice(xol,1);
            xr=xr.join('.'); // multiple . in name
            }else{
            xr=xo[0]; //filename=xr
            xt=xo[1]; //file ext=xt
            }
            xp.splice(xl,1); //remove file
            xf=xp.join('/'); //folder=xf , also corrects slashes
            
            //result
            alert("filepath: "+x+"\n folder: "+xf+"("+xl+")\n file: "+xn+"\n filename: "+xr+"\n .ext:  "+xt)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-04-28
              • 2021-08-13
              • 2013-11-06
              • 1970-01-01
              • 2018-09-02
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多