Javascript - Cara mengekstrak nama file dari kontrol input file

117

Ketika pengguna memilih file di halaman web, saya ingin dapat mengekstrak nama file saja.

Saya memang mencoba fungsi str.search tetapi tampaknya gagal ketika nama filenya seperti ini: c: \ uploads \ ilike.this.file.jpg .

Bagaimana kita bisa mengekstrak nama file saja tanpa ekstensi?

Yogi Yang 007
sumber

Jawaban:

127

Dengan asumsi <input type = "file"> Anda memiliki id unggahan , semoga ini bisa membantu:

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
sumber
Terima kasih ini sepertinya berfungsi dengan baik, tetapi saya hanya ingin nama file tanpa ekstensi. Bagaimana saya bisa melakukannya dalam kode di atas.
Yogi Yang 007
Saya menambahkan dua baris kode ini untuk mengekstrak hanya nama file tanpa ekstensi: "filename = filename.substring (0, filename.length-4); filename = filename.toLowerCase ();"
Yogi Yang 007
13
Tidak, Anda tidak ingin melakukannya seperti kata Yogi Yang. Sebaliknya gunakan: filename = filename.substring(0, filename.lastIndexOf('.'));Karena caranya akan gagal dengan ekstensi karakter lebih dari 3, jadi: .html, .jpeg dll.
Yeti
1
bagaimana cara mendapatkan nama file jika ada banyak pilihan file?
avngr
Mengapa tidak menghitung startIndex seperti itu? var startIndex = Math.max(fullPath.lastIndexOf('\\'), fullPath.lastIndexOf('/')) + 1;
nollidge
196

Untuk memisahkan string ({filepath} / {filename}) dan mendapatkan nama file Anda bisa menggunakan sesuatu seperti ini:

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

"Metode pop menghapus elemen terakhir dari array dan mengembalikan nilai tersebut ke pemanggil."
Jaringan Pengembang Mozilla

Contoh:

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

Anda mendapatkan: "file.txt"

VallaDanger
sumber
5
Anda juga dapat melakukannya hanya dengan regex dan tanpa operasi array:var filename = filepath.replace(/^.*?([^\\\/]*)$/, '$1');
vog
1
Jawaban vog sangat dekat dengan 100% jawaban akurat untuk pertanyaan (kecuali perlu menghapus ekstensi.) Nama file tidak berbeda dari string lainnya.
Jon Watte
1
Regex terpisah dapat disingkat menjadi [\\/]. Selain itu, ia juga diminta untuk menghapus ekstensi file. Untuk solusi lengkap, lihat: stackoverflow.com/a/32156800/19163
vog
multiplatform, ringkas. Bagus.
Marc
Solusi hebat, saya tidak mengerti cara kerjanya dan itulah mengapa lebih menyukainya!
Chatoxz
92

Saat ini ada cara yang jauh lebih sederhana:

var fileInput = document.getElementById('upload');   
var filename = fileInput.files[0].name;
maxime schoeni
sumber
5
Periksa fileInput.files.lengthsebelum menelepon .name, jika pengguna mengklik batal.
marcovtwout
29

Sangat sederhana

let file = $("#fileupload")[0].files[0]; 
file.name
Uchenna
sumber
Jika Anda menggunakan TypeScript, maka $ ("# fileupload") [0] ["files"] [0];
Morvael
18

Asumsi:

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

JavaScriptnya adalah:

var fileName = document.getElementById('theFile').files[0].name;
Xedret
sumber
8
var pieces = str.split('\\');
var filename = pieces[pieces.length-1];
TM.
sumber
Ini mengasumsikan bahwa pengguna menjalankan Windows. Sistem operasi lain menggunakan pemisah jalur file yang berbeda.
Quentin
Apakah Anda perlu memeriksa karakter '/' juga untuk pengguna non-Windows misalnya if (! Pieces) {str.split ('/'); }? Solusi sederhana yang bagus meskipun +1
Ian Oxley
IIRC, IE adalah satu-satunya browser yang memberikan jalur lengkap file ... Anda tidak perlu membaginya di browser lain seperti Firefox, jadi masih berfungsi. Meskipun saya akui, saya belum mencoba SETIAP browser linux / unix.
TM.
6
str.split (/ (\\ | \ /) / g); untuk windows dan * nix
Tracker1
@TM. Chrome menggunakan variabel jalur palsu untuk keamanan yang jelek; iirc berbeda tergantung pada OS apa yang Anda gunakan.
lededje
5

Saya berasumsi bahwa Anda ingin menghapus semua ekstensi, yaitu /tmp/test/somefile.tar.gzuntuksomefile .

Pendekatan langsung dengan regex:

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

Pendekatan alternatif dengan operasi regex dan array:

var filename = filepath.split(/[\\/]/g).pop().split('.')[0];
vog
sumber
1
Ini tidak menghapus ekstensi, seperti yang diminta.
Jon Watte
Tetap. Terima kasih atas petunjuknya!
vog
4

Saya baru saja membuat versi saya sendiri. Fungsi saya dapat digunakan untuk mengekstrak apa pun yang Anda inginkan darinya, jika Anda tidak membutuhkan semuanya, maka Anda dapat dengan mudah menghapus beberapa kode.

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

Akan menampilkan yang berikut:

  • File dengan nama 'testcase1' berekstensi: 'jpeg' ada di direktori: 'C: \ blabla \ blaeobuaeu'
  • File dengan nama 'testcase2' memiliki ekstensi: 'png' ada di direktori: '/ tmp / blabla'
  • File dengan nama 'testcase3' berekstensi: 'htm' ada di direktori: ''
  • Direktori dengan nama 'Testcase4' berekstensi: '' ada di direktori: 'C:'
  • Direktori dengan nama 'fileWithoutDots' memiliki ekstensi: '' ada di direktori: '/dir.with.dots'
  • Direktori dengan nama '' berekstensi: '' ada di direktori: '/dir.with.dots/another.dir'

Dengan && nOffset+1 === str.lengthditambahkan ke isDirectory:

  • File dengan nama 'testcase1' berekstensi: 'jpeg' ada di direktori: 'C: \ blabla \ blaeobuaeu'
  • File dengan nama 'testcase2' memiliki ekstensi: 'png' ada di direktori: '/ tmp / blabla'
  • File dengan nama 'testcase3' berekstensi: 'htm' ada di direktori: ''
  • Direktori dengan nama 'Testcase4' berekstensi: '' ada di direktori: 'C:'
  • Direktori dengan nama 'fileWithoutDots' memiliki ekstensi: '' ada di direktori: '/dir.with.dots'
  • Direktori dengan nama '' berekstensi: '' ada di direktori: '/dir.with.dots/another.dir'

Mengingat kasus uji, Anda dapat melihat fungsi ini bekerja cukup kuat dibandingkan dengan metode lain yang diusulkan di sini.

Catatan untuk pemula tentang \\: \ adalah karakter pelolosan, misalnya \ n berarti baris baru dan tab \ ta. Untuk memungkinkan penulisan \ n, Anda harus benar-benar mengetik \\ n.

Yeti
sumber
1
Hati-hati dengan jalur ini: dir.with.dots / fileWithoutDots karena Anda akan mendapatkan eOffset kurang dari nOffset dan membingungkan ekspresi ekstraksi.
Jesse Chisholm
Ya, perbaiki. Sekarang itu harus bekerja dengan baik juga (ditambahkan && eOffset < nOffset).
Yeti
2

Masukan : C:\path\Filename.ext
Keluaran :Filename

Dalam kode HTML, atur nilai File onChangeseperti ini ...

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

Mengasumsikan id textfield Anda adalah '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
sumber
1

Tak satu pun dari jawaban yang sangat disukai benar-benar memberikan "hanya nama file tanpa ekstensi" dan solusi lainnya adalah kode yang terlalu banyak untuk pekerjaan sederhana seperti itu.

Saya pikir ini harus menjadi satu baris untuk setiap programmer JavaScript. Ini adalah ekspresi reguler yang sangat sederhana:

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

Pertama, lepaskan apa pun hingga garis miring terakhir, jika ada.

Kemudian, lepaskan apa pun setelah periode terakhir, jika ada.

Sederhana, kuat, menerapkan persis apa yang diminta. Apakah saya melewatkan sesuatu?

Jon Watte
sumber
1
"ekspresi reguler yang sangat sederhana" ... Sebenarnya ini adalah dua ekspresi reguler. :-) Lihat jawaban saya untuk solusi regex tunggal.
vog
Ya, ada juga penulisan ulang yang jelas untuk mengemas kedua regex tersebut menjadi satu regex menggunakan operator pipa (|). Saya pikir kode seperti yang tertulis lebih jelas, tetapi berjalan melalui string dua kali, yang akan menjadi masalah jika string umumnya cukup panjang. (Jalur file biasanya tidak, tapi bisa.)
Jon Watte
1
Saya hanya rewel. Tolong jangan anggap itu serius. Tidak perlu mengoptimalkan, semua solusi yang diusulkan sudah lebih dari cukup cepat. Jalur file yang sangat panjang masih kilobyte, bukan gigabyte. Dan fungsi ini akan dipicu sekali per unggahan file, bukan 1000x dalam satu batch. Satu-satunya hal yang penting di sini adalah kebenaran dan kejelasan kode.
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
}

Bagaimana cara menghapus ekstensi

Mikel
sumber
1
Ini melewatkan bagian penting dari pertanyaan, "ekstrak hanya nama file tanpa ekstensi". Ini membantu untuk membaca pertanyaan dengan seksama terlebih dahulu sebelum melompat untuk menjawabnya.
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.
sumber
0

Tak satu pun dari jawaban di atas berfungsi untuk saya, berikut adalah solusi saya yang memperbarui input yang dinonaktifkan dengan nama file:

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

Jika Anda menggunakan jQuery maka

$("#fileupload").val();
Rajat Bansal
sumber
val () sebenarnya akan mengembalikan seluruh jalur file yang tidak dia inginkan.
FabricioG