Javascript - So extrahieren Sie Dateinamen aus einem Dateieingabesteuerelement


117

Wenn ein Benutzer eine Datei auf einer Webseite auswählt, möchte ich nur den Dateinamen extrahieren können.

Ich habe die Funktion str.search ausprobiert, aber es scheint fehlzuschlagen, wenn der Dateiname ungefähr so ​​lautet: c: \ uploads \ ilike.this.file.jpg .

Wie können wir nur den Dateinamen ohne Erweiterung extrahieren?

Antworten:


127

Angenommen, Ihre <input type = "file"> hat eine ID zum Hochladen, sollte dies hoffentlich den Trick tun:

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

Danke, das scheint gut zu funktionieren, aber ich möchte nur einen Dateinamen ohne Erweiterung. Wie kann ich das im obigen Code machen?
Yogi Yang 007

Ich habe diese beiden Codezeilen hinzugefügt, um nur den Dateinamen ohne Erweiterung zu extrahieren: "filename = filename.substring (0, filename.length-4); filename = filename.toLowerCase ();"
Yogi Yang 007

13
Nein, du willst es nicht so machen, wie Yogi Yang sagt. Verwenden Sie stattdessen: filename = filename.substring(0, filename.lastIndexOf('.'));Weil sein Weg mit Erweiterungen von mehr als 3 Zeichen fehlschlägt, also: .html, .jpeg usw.
Yeti

1
Wie erhalte ich die Dateinamen bei Auswahl mehrerer Dateien?
avngr

Warum nicht einfach startIndex so berechnen? var startIndex = Math.max(fullPath.lastIndexOf('\\'), fullPath.lastIndexOf('/')) + 1;
Nollidge

196

Um die Zeichenfolge ({Dateipfad} / {Dateiname}) zu teilen und den Dateinamen abzurufen, können Sie Folgendes verwenden:

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

"Die Pop-Methode entfernt das letzte Element aus einem Array und gibt diesen Wert an den Aufrufer zurück."
Mozilla Developer Network

Beispiel:

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

du erhältst: "file.txt"


5
Sie können dies auch nur mit regulären Ausdrücken und ohne Array-Operation tun:var filename = filepath.replace(/^.*?([^\\\/]*)$/, '$1');
Vog

1
Die Antwort von vog kommt der 100% genauen Antwort auf die Frage sehr nahe (außer dass die Erweiterung entfernt werden muss). Ein Dateiname unterscheidet sich nicht von anderen Zeichenfolgen.
Jon Watte

1
Der geteilte Regex kann auf verkürzt werden [\\/]. Darüber hinaus wurde auch darum gebeten, die Dateierweiterung zu entfernen. Eine vollständige Lösung finden Sie unter : stackoverflow.com/a/32156800/19163
VOG

Multiplattform, prägnant. Toll.
Marc

Tolle Lösung, ich verstehe nicht, wie es funktioniert und deshalb mag ich es mehr!
Chatoxz

92

Heutzutage gibt es einen viel einfacheren Weg:

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

5
Überprüfen Sie fileInput.files.lengthvor dem Anruf .name, ob der Benutzer auf Abbrechen geklickt hat.
Marcovtwout

29

Sehr einfach

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

Wenn Sie TypeScript verwenden, ist es $ ("# fileupload") [0] ["files"] [0];
Morvael

18

Angenommen:

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

Das JavaScript wäre:

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

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

Dies setzt voraus, dass der Benutzer Windows ausführt. Andere Betriebssysteme verwenden andere Dateipfadtrennzeichen.
Quentin

Müssen Sie auch für Nicht-Windows-Benutzer nach dem Zeichen '/' suchen, z. B. if (! Pieces) {str.split ('/'); }? Schöne einfache Lösung obwohl +1
Ian Oxley

IIRC, IE ist der einzige Browser, der ohnehin den vollständigen Pfad der Datei angibt ... Sie müssen nicht auf andere Browser wie Firefox aufteilen, damit es weiterhin funktioniert. Obwohl ich zugebe, dass ich nicht JEDEN Linux / Unix-Browser ausprobiert habe.
TM.

6
str.split (/ (\\ | \ /) / g); für Windows und * nix
Tracker1

@ TM. Chrome verwendet aus Sicherheitsgründen eine gefälschte Pfadvariable, die hässlich ist. Je nachdem, auf welchem ​​Betriebssystem Sie sich befinden, ist dies unterschiedlich.
Lededje

5

Ich gehe davon aus, dass Sie alle Erweiterungen entfernen möchten, dh /tmp/test/somefile.tar.gzbissomefile .

Direkter Ansatz mit Regex:

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

Alternativer Ansatz mit Regex- und Array-Operation:

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

1
Dadurch wird die Erweiterung nicht wie gewünscht entfernt.
Jon Watte

Fest. Danke für den Tipp!
Vog

4

Ich habe gerade meine eigene Version davon gemacht. Meine Funktion kann verwendet werden, um alles zu extrahieren, was Sie wollen. Wenn Sie nicht alles benötigen, können Sie einfach Code entfernen.

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

Gibt Folgendes aus:

  • Datei mit dem Namen 'testcase1' hat die Erweiterung: 'jpeg' befindet sich im Verzeichnis: 'C: \ blabla \ blaeobuaeu'
  • Datei mit dem Namen 'testcase2' hat die Erweiterung: 'png' befindet sich im Verzeichnis: '/ tmp / blabla'
  • Datei mit dem Namen 'testcase3' hat die Erweiterung: 'htm' befindet sich im Verzeichnis: ''
  • Verzeichnis mit dem Namen 'Testcase4' hat die Erweiterung: '' befindet sich im Verzeichnis: 'C:'
  • Verzeichnis mit dem Namen 'fileWithoutDots' hat die Erweiterung: '' befindet sich im Verzeichnis: '/dir.with.dots'
  • Verzeichnis mit dem Namen '' hat die Erweiterung: '' befindet sich im Verzeichnis: '/dir.with.dots/another.dir'

Mit && nOffset+1 === str.lengthhinzugefügt zu isDirectory:

  • Datei mit dem Namen 'testcase1' hat die Erweiterung: 'jpeg' befindet sich im Verzeichnis: 'C: \ blabla \ blaeobuaeu'
  • Datei mit dem Namen 'testcase2' hat die Erweiterung: 'png' befindet sich im Verzeichnis: '/ tmp / blabla'
  • Datei mit dem Namen 'testcase3' hat die Erweiterung: 'htm' befindet sich im Verzeichnis: ''
  • Verzeichnis mit dem Namen 'Testcase4' hat die Erweiterung: '' befindet sich im Verzeichnis: 'C:'
  • Verzeichnis mit dem Namen 'fileWithoutDots' hat die Erweiterung: '' befindet sich im Verzeichnis: '/dir.with.dots'
  • Verzeichnis mit dem Namen '' hat die Erweiterung: '' befindet sich im Verzeichnis: '/dir.with.dots/another.dir'

In Anbetracht der Testfälle können Sie sehen, dass diese Funktion im Vergleich zu den anderen hier vorgeschlagenen Methoden recht robust funktioniert.

Hinweis für Neulinge, dass \\: \ ein Escape-Zeichen ist, z. B. \ n bedeutet eine neue Zeile und eine \ ta-Registerkarte. Um das Schreiben von \ n zu ermöglichen, müssen Sie tatsächlich \\ n eingeben.


1
Achten Sie auf diesen Pfad: dir.with.dots / fileWithoutDots, da Sie eOffset kleiner als nOffset erhalten und die Extraktionsausdrücke verwirren.
Jesse Chisholm

Ja, es wurde behoben. Nun sollte das auch richtig funktionieren (hinzugefügt && eOffset < nOffset).
Yeti

2

Eingabe : C:\path\Filename.ext
Ausgabe :Filename

Stellen Sie im HTML-Code den onChangeWert für " Datei" wie folgt ein ...

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

Angenommen, Ihre Textfeld-ID lautet '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

Keine der hoch bewerteten Antworten enthält tatsächlich "nur den Dateinamen ohne Erweiterung", und die anderen Lösungen sind viel zu viel Code für einen so einfachen Job.

Ich denke, dies sollte ein Einzeiler für jeden JavaScript-Programmierer sein. Es ist ein sehr einfacher regulärer Ausdruck:

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

Entfernen Sie zuerst alles bis zum letzten Schrägstrich, falls vorhanden.

Ziehen Sie dann nach der letzten Periode etwas aus, falls vorhanden.

Es ist einfach, es ist robust, es implementiert genau das, was verlangt wird. Vermisse ich etwas


1
"ein sehr einfacher regulärer Ausdruck" ... Nun, eigentlich sind dies zwei reguläre Ausdrücke. :-) Siehe meine Antwort für eine Single-Regex-Lösung.
Vog

Ja, es gibt auch eine offensichtliche Neuschreibung, um diese beiden regulären Ausdrücke mit dem Pipe-Operator (|) in einen einzigen regulären Ausdruck zu packen. Ich denke, der geschriebene Code ist klarer, aber er läuft zweimal durch die Zeichenfolge, was ein Problem wäre, wenn die Zeichenfolge im Allgemeinen ziemlich lang ist. (Dateipfade sind normalerweise nicht, können es aber sein.)
Jon Watte

1
Ich habe nur nicht gepickt. Bitte nimm das nicht ernst. Es besteht kein Optimierungsbedarf, alle vorgeschlagenen Lösungen sind mehr als schnell genug. Sehr lange Dateipfade sind immer noch Kilobyte, keine Gigabyte. Und diese Funktion wird einmal pro Datei-Upload ausgelöst, nicht 1000x in einem Stapel. Die einzigen Dinge, die hier wichtig sind, sind die Richtigkeit und Klarheit des Codes.
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
}

So entfernen Sie die Erweiterung


1
Dabei fehlt ein wichtiger Teil der Frage "Nur den Dateinamen ohne Erweiterung extrahieren". Es ist hilfreich, die Frage zuerst sorgfältig zu lesen, bevor Sie zur Beantwortung springen.
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

Keine der oben genannten Antworten hat bei mir funktioniert. Hier ist meine Lösung, die eine deaktivierte Eingabe mit dem Dateinamen aktualisiert:

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

-2

Wenn Sie dann jQuery verwenden

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

val () würde tatsächlich den gesamten Dateipfad zurückgeben, was er nicht will.
FabricioG
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.