JavaScript-ファイル入力コントロールからファイル名を抽出する方法


117

ユーザーがWebページでファイルを選択したときに、ファイル名だけを抽出できるようにしたいと考えています。

str.search関数を試してみましたが、ファイル名がc:\ uploads \ ilike.this.file.jpgのような場合は失敗するようです

拡張子なしでファイル名だけを抽出するにはどうすればよいですか?

回答:


127

あなたと仮定の<input type =「ファイルを」>の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

次の2行のコードを追加して、拡張子なしのファイル名のみを抽出します: "filename = filename.substring(0、filename.length-4); filename = filename.toLowerCase();"
Yogi Yang 007

13
いいえ、ヨギ・ヤンが言うようにそれをしたくないのです。代わりに使用してください: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 Developer Network

例:

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

あなたが得る: "file.txt"


5
また、単に正規表現とし、任意の配列の操作なしでそれを行うことができます:var filename = filepath.replace(/^.*?([^\\\/]*)$/, '$1');
VOG

1
vogの回答は、質問に対する100%正確な回答に非常に近い(拡張子を取り除く必要がある場合を除く)。ファイル名は他の文字列と同じです。
Jon Watte

1
分割正規表現はに短縮できます[\\/]。また、ファイル拡張子の削除も求められました。完全なソリューションについては、stackoverflow.com
vog

マルチプラットフォーム、簡潔。すごい。
マルク

素晴らしい解決策、私はそれがどのように機能するのか理解していないので、それがもっと好きなのです!
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

@TM。Chromeは安全のために醜いパス変数を使用しています。iirc使用しているOSによって異なります。
lededje 2013年

5

私はあなたがすべての拡張子、すなわち/tmp/test/somefile.tar.gzを取り除きたいと思いますsomefile

正規表現による直接的なアプローチ:

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

正規表現と配列演算を使用した代替アプローチ:

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

1
要求されたように、これは拡張機能を取り除きません。
Jon Watte

修繕。ヒントをありがとう!
2016

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は、nOffsetよりも小さいeOffsetを取得し、抽出式を混乱させるためです。
ジェシーチザム2014年

うん、直した。これで正しく動作するはずです(を追加&& eOffset < nOffset)。
イエティ

2

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

1

非常に支持された回答のどちらも実際には「拡張子なしの単なるファイル名」を提供しておらず、他のソリューションはそのような単純な仕事にはあまりにも多くのコードです。

これは、JavaScriptプログラマーにとっては重要なことです。これは非常に単純な正規表現です。

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

最初に、もしあれば最後のスラッシュまで何でも取り除きます。

次に、最後のピリオドが存在する場合は、それ以降のものを取り除きます。

シンプルで、堅牢で、要求されたものを正確に実装します。何か不足していますか?


1
「非常に単純な正規表現」...まあ、実際にはこれらは2つの正規表現です。:-)単一正規表現ソリューションについての私の答えを参照してください。
2016

はい、パイプ(|)演算子を使用して、これら2つの正規表現を単一の正規表現にパックする明らかな書き直しもあります。記述されたコードはより明確だと思いますが、文字列を2回実行するため、文字列が一般的にかなり長い場合は問題になります。(通常、ファイルパスはそうではありませんが、そうすることができます。)
Jon Watte

1
私はつまらないものばかりでした。それを真剣に受け止めないでください。最適化する必要はありません。提案されたすべてのソリューションは十分に高速です。非常に長いファイルパスはギガバイトではなく、キロバイトのままです。また、この機能はファイルのアップロードごとに1回トリガーされ、バッチでは1000倍ではトリガーされません。ここで重要なのは、コードの正確さと明確さだけです。
2016

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

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>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.