Javascript - Jak wyodrębnić nazwę pliku z kontrolki wejściowej pliku


117

Gdy użytkownik wybierze plik na stronie internetowej, chcę mieć możliwość wyodrębnienia tylko nazwy pliku.

Wypróbowałem funkcję str.search, ale wydaje się, że kończy się to niepowodzeniem, gdy nazwa pliku jest taka: c: \ uploads \ ilike.this.file.jpg .

Jak możemy wyodrębnić tylko nazwę pliku bez rozszerzenia?

Odpowiedzi:


127

Zakładając, że <input type = "file"> ma identyfikator przesłania, to powinno załatwić sprawę:

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

Dzięki temu wygląda na to, że działa dobrze, ale chcę tylko nazwy pliku bez rozszerzenia. Jak mogę to zrobić w powyższym kodzie.
Yogi Yang 007

Dodałem te dwa wiersze kodu, aby wyodrębnić tylko nazwę pliku bez rozszerzenia: "filename = filename.substring (0, filename.length-4); filename = filename.toLowerCase ();"
Yogi Yang 007

13
Nie, nie chcesz tego robić w ten sposób, mówi Yogi Yang. Zamiast tego użyj: filename = filename.substring(0, filename.lastIndexOf('.'));Ponieważ jego sposób zawiedzie przy rozszerzeniach większej liczby znaków niż 3, a więc: .html, .jpeg itp.
Yeti

1
jak uzyskać nazwy plików w przypadku wielokrotnego wyboru plików?
avngr

Dlaczego po prostu nie obliczyć startIndex w ten sposób? var startIndex = Math.max(fullPath.lastIndexOf('\\'), fullPath.lastIndexOf('/')) + 1;
nollidge

196

Aby podzielić ciąg ({filepath} / {filename}) i uzyskać nazwę pliku, możesz użyć czegoś takiego:

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

„Metoda pop usuwa ostatni element z tablicy i zwraca tę wartość do obiektu wywołującego”.
Mozilla Developer Network

Przykład:

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

dostajesz: "file.txt"


5
Możesz to również zrobić za pomocą var filename = filepath.replace(/^.*?([^\\\/]*)$/, '$1');
wyrażeń regularnych

1
Odpowiedź vog jest naprawdę bliska 100% dokładnej odpowiedzi na pytanie (z wyjątkiem konieczności usunięcia rozszerzenia). Nazwa pliku nie różni się od żadnego innego ciągu.
Jon Watte

1
Podzielone wyrażenie regularne można skrócić do [\\/]. Ponadto został poproszony o usunięcie rozszerzenia pliku. Aby uzyskać kompletne rozwiązanie, zobacz: stackoverflow.com/a/32156800/19163
vog

wieloplatformowy, zwięzły. Wspaniały.
Marc

Świetne rozwiązanie, nie rozumiem, jak to działa i dlatego bardziej mi się podoba!
Chatoxz

92

Obecnie jest znacznie prostszy sposób:

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

5
Sprawdź, fileInput.files.lengthzanim zadzwonisz .name, na wypadek, gdyby użytkownik kliknął Anuluj.
marcovtwout

29

Bardzo prosty

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

Jeśli używasz TypeScript, to $ ("# fileupload") [0] ["files"] [0];
Morvael

18

Zarozumiały:

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

JavaScript wyglądałby następująco:

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

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

Zakłada się, że użytkownik korzysta z systemu Windows. Inne systemy operacyjne używają różnych separatorów ścieżek plików.
Quentin

Czy musiałbyś sprawdzić znak „/” również dla użytkowników spoza systemu Windows, np. If (! Pieces) {str.split ('/'); }? Ale fajne proste rozwiązanie +1
Ian Oxley

IIRC, IE jest jedyną przeglądarką, która i tak podaje pełną ścieżkę do pliku ... Nie musisz dzielić się na inne przeglądarki, takie jak Firefox, więc nadal działa. Chociaż przyznaję, że nie próbowałem KAŻDEJ przeglądarki linux / unix.
TM.

6
str.split (/ (\\ | \ /) / g); dla Windows i * nix
Tracker1

@TM. Chrome używa fałszywej zmiennej ścieżki dla bezpieczeństwa, co jest brzydkie; iirc różni się w zależności od używanego systemu operacyjnego.
lededje

5

Zakładam, że chce się rozebrać wszystkie rozszerzenia, czyli /tmp/test/somefile.tar.gzdo somefile.

Bezpośrednie podejście z wyrażeniem regularnym:

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

Alternatywne podejście z operacjami regex i tablic:

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

1
Nie powoduje to usunięcia rozszerzenia, o co prosiliśmy.
Jon Watte

Naprawiony. Dzięki za podpowiedź!
vog

4

Właśnie stworzyłem własną wersję tego. Moją funkcję można wykorzystać do wyodrębnienia z niej wszystkiego, co chcesz, jeśli nie potrzebujesz tego wszystkiego, możesz łatwo usunąć część kodu.

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

Wyświetli następujące informacje:

  • Plik o nazwie „testcase1” ma rozszerzenie: „jpeg” znajduje się w katalogu: „C: \ blabla \ blaeobuaeu”
  • Plik o nazwie „testcase2” ma rozszerzenie: „png” znajduje się w katalogu: „/ tmp / blabla”
  • Plik o nazwie „testcase3” ma rozszerzenie: „htm” znajduje się w katalogu: „”
  • Katalog o nazwie „Testcase4” ma rozszerzenie: „” znajduje się w katalogu: „C:”
  • Katalog o nazwie „fileWithoutDots” ma rozszerzenie: „” znajduje się w katalogu: „/dir.with.dots”
  • Katalog o nazwie „” ma rozszerzenie: „” znajduje się w katalogu: „/dir.with.dots/another.dir”

Z && nOffset+1 === str.lengthdodatkiem do isDirectory:

  • Plik o nazwie „testcase1” ma rozszerzenie: „jpeg” znajduje się w katalogu: „C: \ blabla \ blaeobuaeu”
  • Plik o nazwie „testcase2” ma rozszerzenie: „png” znajduje się w katalogu: „/ tmp / blabla”
  • Plik o nazwie „testcase3” ma rozszerzenie: „htm” znajduje się w katalogu: „”
  • Katalog o nazwie „Testcase4” ma rozszerzenie: „” znajduje się w katalogu: „C:”
  • Katalog o nazwie „fileWithoutDots” ma rozszerzenie: „” znajduje się w katalogu: „/dir.with.dots”
  • Katalog o nazwie „” ma rozszerzenie: „” znajduje się w katalogu: „/dir.with.dots/another.dir”

Biorąc pod uwagę przypadki testowe, możesz zobaczyć, że ta funkcja działa dość solidnie w porównaniu z innymi proponowanymi tutaj metodami.

Uwaga dla początkujących na temat znaku \\: \ to znak zmiany znaczenia, na przykład \ n oznacza znak nowej linii i \ ta tabulator. Aby było możliwe pisanie \ n, musisz faktycznie wpisać \\ n.


1
Uważaj na tę ścieżkę: dir.with.dots / fileWithoutDots, ponieważ otrzymasz eOffset mniej niż nOffset i pomylisz wyrażenia wyodrębniania.
Jesse Chisholm

Tak, naprawiłem to. Teraz to też powinno działać poprawnie (dodane && eOffset < nOffset).
Yeti

2

Wejście : C:\path\Filename.ext
wyjście :Filename

W kodzie HTML ustaw onChangewartość pliku w ten sposób ...

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

Zakładając, że twój identyfikator pola tekstowego to `` 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

Żadna z wysoko ocenianych odpowiedzi w rzeczywistości nie zawiera „tylko nazwy pliku bez rozszerzenia”, a inne rozwiązania zawierają zbyt dużo kodu, aby wykonać tak prostą pracę.

Myślę, że to powinno być jednowierszowe dla każdego programisty JavaScript. To bardzo proste wyrażenie regularne:

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

Najpierw usuń wszystko do ostatniego ukośnika, jeśli jest obecny.

Następnie usuń wszystko po ostatnim okresie, jeśli jest obecny.

Jest proste, solidne, implementuje dokładnie to, o co się prosi. Czy coś mi brakuje?


1
„bardzo proste wyrażenie regularne”… Cóż, właściwie są to dwa wyrażenia regularne. :-) Zobacz moją odpowiedź na rozwiązanie z pojedynczym wyrażeniem regularnym.
vog

Tak, istnieje również oczywiste ponowne zapisanie, aby spakować te dwa wyrażenia regularne do jednego wyrażenia regularnego przy użyciu operatora potoku (|). Myślę, że napisany kod jest bardziej przejrzysty, ale dwukrotnie przechodzi przez ciąg, co byłoby problemem, gdyby ciąg był ogólnie dość długi. (Ścieżki plików zazwyczaj nie są, ale mogą być.)
Jon Watte

1
Po prostu szukałem czubka. Proszę, nie traktuj tego poważnie. Nie ma potrzeby optymalizacji, wszystkie proponowane rozwiązania są wystarczająco szybkie. Bardzo długie ścieżki plików to nadal kilobajty, a nie gigabajty. Ta funkcja zostanie uruchomiona raz na załadowanie pliku, a nie 1000 razy w partii. Jedyne, co się tutaj liczy, to poprawność i przejrzystość kodu.
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
}

Jak usunąć rozszerzenie


1
To pomija ważną część pytania, „wypakuj tylko nazwę pliku bez rozszerzenia”. Dobrze jest najpierw uważnie przeczytać pytanie, zanim zaczniesz na nie odpowiedzieć.
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

Żadna z powyższych odpowiedzi nie zadziałała dla mnie, oto moje rozwiązanie, które aktualizuje wyłączone wejście o nazwę pliku:

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.