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?

Yogi Yang 007
źródło

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);
}
Ian Oxley
źródło
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"

VallaDanger
źródło
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;
maxime schoeni
źródło
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
Uchenna
źródło
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;
Xedret
źródło
8
var pieces = str.split('\\');
var filename = pieces[pieces.length-1];
TM.
źródło
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];
vog
źródło
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.

Yeti
źródło
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>
DxTx
źródło
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?

Jon Watte
źródło
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

Mikel
źródło
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
Luca C.
źródło
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>
sigi
źródło
-2

Jeśli używasz jQuery to

$("#fileupload").val();
Rajat Bansal
źródło
val () faktycznie zwróciłby całą ścieżkę do pliku, czego nie chce.
FabricioG