Javascript - Come estrarre il nome del file da un controllo di input di file


117

Quando un utente seleziona un file in una pagina web, voglio essere in grado di estrarre solo il nome del file.

Ho provato la funzione str.search ma sembra fallire quando il nome del file è qualcosa del genere: c: \ uploads \ ilike.this.file.jpg .

Come possiamo estrarre solo il nome del file senza estensione?

Risposte:


127

Supponendo che il tuo <input type = "file"> abbia un ID di caricamento, si spera che questo dovrebbe fare il trucco:

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

Grazie, questo sembra funzionare bene, ma voglio solo il nome del file senza estensione. Come posso farlo nel codice sopra.
Yogi Yang 007

Ho aggiunto queste due righe di codice per estrarre solo il nome del file senza estensione: "filename = filename.substring (0, filename.length-4); filename = filename.toLowerCase ();"
Yogi Yang 007

13
No, non vuoi farlo nel modo in cui dice Yogi Yang. Usa invece: filename = filename.substring(0, filename.lastIndexOf('.'));Perché il suo metodo fallirà con estensioni di più caratteri di 3, quindi: .html, .jpeg ecc.
Yeti

1
come ottenere i nomi dei file in caso di selezione di più file?
avngr

Perché non calcolare semplicemente startIndex in questo modo? var startIndex = Math.max(fullPath.lastIndexOf('\\'), fullPath.lastIndexOf('/')) + 1;
nollidge

196

Per dividere la stringa ({filepath} / {filename}) e ottenere il nome del file potresti usare qualcosa del genere:

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

"Il metodo pop rimuove l'ultimo elemento da un array e restituisce quel valore al chiamante."
Mozilla Developer Network

Esempio:

a partire dal: "/home/user/file.txt".split(/(\\|\/)/g).pop()

ottieni: "file.txt"


5
Puoi anche farlo solo con regex e senza alcuna operazione di array:var filename = filepath.replace(/^.*?([^\\\/]*)$/, '$1');
vog

1
La risposta di vog è molto vicina alla risposta accurata al 100% alla domanda (tranne per la necessità di rimuovere l'estensione.) Un nome di file non è diverso da qualsiasi altra stringa.
Jon Watte

1
La regex divisa può essere abbreviata in [\\/]. Inoltre, è stato chiesto di rimuovere anche l'estensione del file. Per una soluzione completa, vedere: stackoverflow.com/a/32156800/19163
VOG

multipiattaforma, conciso. Grande.
Marc

Ottima soluzione, non capisco come funziona ed è per questo che mi piace di più!
Chatoxz

92

Al giorno d'oggi c'è un modo molto più semplice:

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

5
Verificare fileInput.files.lengthprima di chiamare .name, nel caso in cui l'utente abbia cliccato su Annulla.
marcovtwout

29

Molto semplice

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

Nel caso tu stia usando TypeScript, allora il suo $ ("# fileupload") [0] ["files"] [0];
Morvael

18

assumendo:

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

Il JavaScript sarebbe:

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

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

Ciò presuppone che l'utente stia eseguendo Windows. Altri sistemi operativi utilizzano separatori di percorso file diversi.
Quentin

Dovresti controllare il carattere "/" anche per utenti non Windows, ad esempio if (! Pieces) {str.split ('/'); }? Bella soluzione semplice anche se +1
Ian Oxley

IIRC, IE è l'unico browser che fornisce comunque il percorso completo del file ... Non avrai bisogno di dividerlo su altri browser come Firefox, quindi funziona ancora. Anche se ammetto di non aver provato TUTTI i browser linux / unix.
TM.

6
str.split (/ (\\ | \ /) / g); per windows e * nix
Tracker1

@TM. Chrome utilizza una variabile di percorso falsa per la sicurezza che è brutta; iirc è diverso a seconda del sistema operativo in uso.
lededje

5

Presumo che tu voglia rimuovere tutte le estensioni, cioè /tmp/test/somefile.tar.gzasomefile .

Approccio diretto con regex:

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

Approccio alternativo con regex e operazione su array:

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

1
Questo non toglie l'estensione, come richiesto.
Jon Watte

Fisso. Grazie per il suggerimento!
vog

4

Ho appena creato la mia versione di questo. La mia funzione può essere utilizzata per estrarre tutto ciò che vuoi da esso, se non ti serve tutto, puoi rimuovere facilmente del codice.

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

Produrrà quanto segue:

  • Il file con il nome "testcase1" ha estensione: "jpeg" si trova nella directory: "C: \ blabla \ blaeobuaeu"
  • Il file con il nome "testcase2" ha l'estensione: "png" si trova nella directory: "/ tmp / blabla"
  • Il file con il nome "testcase3" ha l'estensione: "htm" si trova nella directory: ""
  • La directory con il nome "Testcase4" ha l'estensione: "" si trova nella directory: "C:"
  • La directory con il nome "fileWithoutDots" ha l'estensione: "" si trova nella directory: "/dir.with.dots"
  • La directory con il nome "ha estensione:" è nella directory: "/dir.with.dots/another.dir"

Con && nOffset+1 === str.lengthaggiunto a isDirectory:

  • Il file con il nome "testcase1" ha estensione: "jpeg" si trova nella directory: "C: \ blabla \ blaeobuaeu"
  • Il file con il nome "testcase2" ha l'estensione: "png" si trova nella directory: "/ tmp / blabla"
  • Il file con il nome "testcase3" ha l'estensione: "htm" si trova nella directory: ""
  • La directory con il nome "Testcase4" ha l'estensione: "" si trova nella directory: "C:"
  • La directory con il nome "fileWithoutDots" ha l'estensione: "" si trova nella directory: "/dir.with.dots"
  • La directory con il nome "ha estensione:" è nella directory: "/dir.with.dots/another.dir"

Dati i casi di test, puoi vedere che questa funzione funziona in modo abbastanza robusto rispetto agli altri metodi proposti qui.

Nota per i neofiti sul \\: \ è un carattere di escape, ad esempio \ n indica una nuova riga e una scheda \ ta. Per rendere possibile scrivere \ n, devi effettivamente digitare \\ n.


1
Fai attenzione a questo percorso: dir.with.dots / fileWithoutDots poiché otterrai eOffset inferiore a nOffset e confonderai le espressioni di estrazione.
Jesse Chisholm

Sì, risolto. Ora dovrebbe funzionare correttamente anche (aggiunto && eOffset < nOffset).
Yeti

2

Ingresso : C:\path\Filename.ext
Uscita :Filename

Nel codice HTML, imposta il onChangevalore File in questo modo ...

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

Supponendo che l'ID del campo di testo sia "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

Nessuna delle risposte altamente votate fornisce in realtà "solo il nome del file senza estensione" e le altre soluzioni sono troppo codice per un lavoro così semplice.

Penso che questo dovrebbe essere un insegnamento per qualsiasi programmatore JavaScript. È un'espressione regolare molto semplice:

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

Per prima cosa, spoglia qualsiasi cosa fino all'ultima barra, se presente.

Quindi, spoglia tutto dopo l'ultima mestruazione, se presente.

È semplice, è robusto, implementa esattamente ciò che viene richiesto. Mi sto perdendo qualcosa?


1
"un'espressione regolare molto semplice" ... Beh, in realtà queste sono due regex. :-) Vedi la mia risposta per una soluzione a regex singolo.
vog

Sì, c'è anche un'ovvia riscrittura per comprimere queste due espressioni regolari in un'unica espressione regolare usando l'operatore pipe (|). Penso che il codice come scritto sia più chiaro, ma viene eseguito attraverso la stringa due volte, il che sarebbe un problema se la stringa è generalmente piuttosto lunga. (I percorsi dei file in genere non lo sono, ma possono esserlo).
Jon Watte

1
Stavo solo facendo i pignoli. Per favore, non prenderlo sul serio. Non è necessario ottimizzare, tutte le soluzioni proposte sono più che sufficientemente veloci. I percorsi dei file molto lunghi sono ancora kilobyte, non gigabyte. E questa funzione verrà attivata una volta per caricamento di file, non 1000 volte in un batch. Le uniche cose che contano qui sono la correttezza e la chiarezza del codice.
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
}

Come rimuovere l'estensione


1
In questo modo manca una parte importante della domanda, "estrarre solo il nome del file senza estensione". È utile leggere attentamente la domanda prima di saltare per rispondere.
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

Nessuna delle risposte precedenti ha funzionato per me, ecco la mia soluzione che aggiorna un input disabilitato con il nome del 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>

-2

Se stai usando jQuery allora

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

val () restituirebbe effettivamente l'intero percorso del file che è ciò che non vuole.
FabricioG
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.