Come posso ottenere estensioni di file con JavaScript?

Vedi il codice:

var file1 = "50.xsl"; var file2 = "30.doc"; getFileExtension(file1); //returns xsl getFileExtension(file2); //returns doc function getFileExtension(filename) { /*TODO*/ } 

Modifica più recente: molte cose sono cambiate da quando questa domanda è stata inizialmente pubblicata – ci sono molte informazioni veramente buone nella risposta revisionata di wallacer così come l’eccellente ripartizione di VisioN


Modifica: solo perché questa è la risposta accettata; la risposta di wallacer è davvero molto meglio:

 return filename.split('.').pop(); 

La mia vecchia risposta:

 return /[^.]+$/.exec(filename); 

Dovrebbe farlo

Modifica: in risposta al commento di PhiLho, usa qualcosa come:

 return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined; 
 return filename.split('.').pop(); 

Mantieni la semplicità 🙂

Modificare:

Questa è un’altra soluzione non regex che credo sia più efficiente:

 return filename.substring(filename.lastIndexOf('.')+1, filename.length) || filename; 

Ci sono alcuni casi d’angolo che sono meglio gestiti dalla risposta di VisioN qui sotto, in particolare i file senza estensione ( .htaccess etc incluso).

È molto performante e gestisce i casi d’angolo in un modo decisamente migliore restituendo "" invece della stringa intera quando non c’è alcun punto o nessuna stringa prima del punto. È una soluzione molto ben fatta, anche se difficile da leggere. Attaccalo nella tua lib di aiutanti e usalo.

Modifica precedente:

Un’implementazione più sicura se hai intenzione di imbatterti in file senza estensione, o file nascosti senza estensione (vedi il commento di VisioN alla risposta di Tom sopra) sarebbe qualcosa in questo senso

 var a = filename.split("."); if( a.length === 1 || ( a[0] === "" && a.length === 2 ) ) { return ""; } return a.pop(); // feel free to tack .toLowerCase() here if you want 

Se a.length è uno, è un file visibile senza estensione ie. file

Se a[0] === "" e a.length === 2 si tratta di un file nascosto senza estensione, ad es. .htaccess

Spero che questo aiuti a chiarire i problemi con i casi leggermente più complessi. In termini di prestazioni, credo che questa soluzione sia leggermente più lenta della regex nella maggior parte dei browser. Tuttavia, per gli scopi più comuni questo codice dovrebbe essere perfettamente utilizzabile.

La seguente soluzione è veloce e abbastanza breve da utilizzare in operazioni di massa e salva byte extra:

  return fname.slice((fname.lastIndexOf(".") - 1 >>> 0) + 2); 

Ecco un’altra soluzione universale non-regexp su un’unica riga:

  return fname.slice((Math.max(0, fname.lastIndexOf(".")) || Infinity) + 1); 

Entrambi funzionano correttamente con nomi che non hanno estensione (es. Myfile ) o che iniziano con . punto (ad esempio .htaccess ):

  "" --> "" "name" --> "" "name.txt" --> "txt" ".htpasswd" --> "" "name.with.many.dots.myext" --> "myext" 

Se ti interessa la velocità puoi eseguire il benchmark e controllare che le soluzioni fornite siano le più veloci, mentre quella breve è tremendamente veloce:

Confronto di velocità

Come funziona quello corto:

  1. String.lastIndexOf metodo String.lastIndexOf restituisce l’ultima posizione della sottostringa (ad es "." ) Nella stringa specificata (es. fname ). Se la sottostringa non viene trovata, il metodo restituisce -1 .
  2. Le posizioni “inaccettabili” del punto nel nome del file sono -1 e 0 , che si riferiscono rispettivamente a nomi senza estensione (ad es. "name" ) ea nomi che iniziano con punto (es. ".htaccess" ).
  3. L’operatore di spostamento a destra zero-fill ( >>> ) se usato con zero influenza i numeri negativi che trasformano da -1 a 4294967295 e da -2 a 4294967294 , che è utile per mantenere il nome file invariato nei casi limite (una specie di trucco qui).
  4. String.prototype.slice estrae la parte del nome file dalla posizione che è stata calcasting come descritto. Se il numero di posizione è maggiore della lunghezza del metodo stringa restituisce "" .

Se vuoi una soluzione più chiara che funzioni allo stesso modo (oltre al supporto extra del percorso completo), controlla la seguente versione estesa. Questa soluzione sarà più lenta delle precedenti one-liner, ma è molto più facile da capire.

 function getExtension(path) { var basename = path.split(/[\\/]/).pop(), // extract file name from full path ... // (supports `\\` and `/` separators) pos = basename.lastIndexOf("."); // get last position of `.` if (basename === "" || pos < 1) // if file name is empty or ... return ""; // `.` not found (-1) or comes first (0) return basename.slice(pos + 1); // extract extension ignoring `.` } console.log( getExtension("/path/to/file.ext") ); // >> "ext" 

Tutte e tre le varianti dovrebbero funzionare in qualsiasi browser Web sul lato client e possono essere utilizzate anche nel codice NodeJS lato server.

 function getFileExtension(filename) { var ext = /^.+\.([^.]+)$/.exec(filename); return ext == null ? "" : ext[1]; } 

Testato con

 "ab" (=> "b") "a" (=> "") ".hidden" (=> "") "" (=> "") null (=> "") 

Anche

 "abcd" (=> "d") ".ab" (=> "b") "a..b" (=> "b") 
 function getExt(filename) { var ext = filename.split('.').pop(); if(ext == filename) return ""; return ext; } 
 var extension = fileName.substring(fileName.lastIndexOf('.')+1); 
 var parts = filename.split('.'); return parts[parts.length-1]; 
 function file_get_ext(filename) { return typeof filename != "undefined" ? filename.substring(filename.lastIndexOf(".")+1, filename.length).toLowerCase() : false; } 

Codice

 /** * Extract file extension from URL. * @param {String} url * @returns {String} File extension or empty string if no extension is present. */ var getFileExtension = function (url) { "use strict"; if (url === null) { return ""; } var index = url.lastIndexOf("/"); if (index !== -1) { url = url.substring(index + 1); // Keep path without its segments } index = url.indexOf("?"); if (index !== -1) { url = url.substring(0, index); // Remove query } index = url.indexOf("#"); if (index !== -1) { url = url.substring(0, index); // Remove fragment } index = url.lastIndexOf("."); return index !== -1 ? url.substring(index + 1) // Only keep file extension : ""; // No extension found }; 

Test

Si noti che in assenza di una query, il frammento potrebbe essere ancora presente.

 "https://www.example.com:8080/segment1/segment2/page.html?foo=bar#fragment" --> "html" "https://www.example.com:8080/segment1/segment2/page.html#fragment" --> "html" "https://www.example.com:8080/segment1/segment2/.htaccess?foo=bar#fragment" --> "htaccess" "https://www.example.com:8080/segment1/segment2/page?foo=bar#fragment" --> "" "https://www.example.com:8080/segment1/segment2/?foo=bar#fragment" --> "" "" --> "" null --> "" "abcd" --> "d" ".ab" --> "b" ".ab" --> "" "a...b" --> "b" "..." --> "" 

JSLint

0 avvertimenti.

Veloce e funziona correttamente con i percorsi

 (filename.match(/[^\\\/]\.([^.\\\/]+)$/) || [null]).pop() 

Alcuni casi limite

 /path/.htaccess => null /dir.with.dot/file => null 

Le soluzioni che utilizzano split sono lente e le soluzioni con lastIndexOf non gestiscono casi limite.

Prova questo:

 function getFileExtension(filename) { var fileinput = document.getElementById(filename); if (!fileinput) return ""; var filename = fileinput.value; if (filename.length == 0) return ""; var dot = filename.lastIndexOf("."); if (dot == -1) return ""; var extension = filename.substr(dot, filename.length); return extension; } 

Volevo solo condividere questo.

 fileName.slice(fileName.lastIndexOf('.')) 

anche se questo ha una rovina, i file senza estensione restituiranno l’ultima stringa. ma se lo fai, questo risolverà ogni cosa:

  function getExtention(fileName){ var i = fileName.lastIndexOf('.'); if(i === -1 ) return false; return fileName.slice(i) } 
 return filename.replace(/\.([a-zA-Z0-9]+)$/, "$1"); 

edit: Stranamente (o forse non lo è) il $1 nel secondo argomento del metodo replace non sembra funzionare … Scusa.

Ho appena realizzato che non è sufficiente commentare la risposta di p4bl0, sebbene la risposta di Tom risolva chiaramente il problema:

 return filename.replace(/^.*?\.([a-zA-Z0-9]+)$/, "$1"); 

Per la maggior parte delle applicazioni, uno script semplice come

 return /[^.]+$/.exec(filename); 

funzionerebbe bene (come previsto da Tom). Tuttavia questo non è infallibile. Non funziona se viene fornito il seguente nome file:

 image.jpg?foo=bar 

Potrebbe essere un po ‘eccessivo, ma suggerirei di utilizzare un parser di url come questo per evitare errori dovuti a nomi di file imprevedibili.

Usando quella particolare funzione, potresti ottenere il nome del file in questo modo:

 var trueFileName = parse_url('image.jpg?foo=bar').file; 

Ciò produrrà “image.jpg” senza l’url vars. Quindi sei libero di prendere l’estensione del file.

 function func() { var val = document.frm.filename.value; var arr = val.split("."); alert(arr[arr.length - 1]); var arr1 = val.split("\\"); alert(arr1[arr1.length - 2]); if (arr[1] == "gif" || arr[1] == "bmp" || arr[1] == "jpeg") { alert("this is an image file "); } else { alert("this is not an image file"); } } 
 function extension(fname) { var pos = fname.lastIndexOf("."); var strlen = fname.length; if (pos != -1 && strlen != pos + 1) { var ext = fname.split("."); var len = ext.length; var extension = ext[len - 1].toLowerCase(); } else { extension = "No extension found"; } return extension; } 

// utilizzo

estensione ( ‘file.jpeg’)

restituisce sempre l’estensione lower cas in modo da poterlo verificare sui lavori di cambio campo per:

file.JpEg

file (senza estensione)

file. (Noextension)

Se stai cercando un’estensione specifica e ne conosci la lunghezza, puoi usare substr :

 var file1 = "50.xsl"; if (file1.substr(-4) == '.xsl') { // do something } 

Riferimento JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr

Sono molte lune in ritardo per la festa ma per semplicità uso qualcosa del genere

 var fileName = "I.Am.FileName.docx"; var nameLen = fileName.length; var lastDotPos = fileName.lastIndexOf("."); var fileNameSub = false; if(lastDotPos === -1) { fileNameSub = false; } else { //Remove +1 if you want the "." left too fileNameSub = fileName.substr(lastDotPos + 1, nameLen); } document.getElementById("showInMe").innerHTML = fileNameSub; 
 

Una soluzione a una riga che terrà conto anche dei parametri di query e di eventuali caratteri nell’URL.

 string.match(/(.*)\??/i).shift().replace(/\?.*/, '').split('.').pop() // Example // some.url.com/with.in/&ot.s/files/file.jpg?spec=1&.ext=jpg // jpg 

La risposta di Wallacer è buona, ma è necessario un altro controllo.

Se il file non ha estensione, utilizzerà il nome file come estensione che non è buona.

Prova questo:

 return ( filename.indexOf('.') > 0 ) ? filename.split('.').pop().toLowerCase() : 'undefined'; 

Non dimenticare che alcuni file non possono avere estensione, quindi:

 var parts = filename.split('.'); return (parts.length > 1) ? parts.pop() : ''; 

Questa semplice soluzione

 function extension(filename) { var r = /.+\.(.+)$/.exec(filename); return r ? r[1] : null; } 

test

 /* tests */ test('cat.gif', 'gif'); test('main.c', 'c'); test('file.with.multiple.dots.zip', 'zip'); test('.htaccess', null); test('noextension.', null); test('noextension', null); test('', null); // test utility function function test(input, expect) { var result = extension(input); if (result === expect) console.log(result, input); else console.error(result, input); } function extension(filename) { var r = /.+\.(.+)$/.exec(filename); return r ? r[1] : null; } 

Sono sicuro che qualcuno potrà, e lo farà, ridurrà e / o ottimizzerà il mio codice in futuro. Ma, al momento , sono sicuro al 200% che il mio codice funzioni in ogni situazione unica (ad esempio solo con il nome del file , con relativi , relativi alla radice e URL assoluti , con tag # frammento , con stringhe di query ? e qualsiasi altra cosa tu decida di lanciarti), in modo impeccabile e con precisione precisa.

Per prova, visitare: https://projects.jamesandersonjr.com/web/js_projects/get_file_extension_test.php

Ecco il JSFiddle: https://jsfiddle.net/JamesAndersonJr/ffcdd5z3/

Non per essere troppo sicuro di sé, o per far saltare la mia tromba, ma non ho visto alcun blocco di codice per questo compito (trovando l’estensione di file ‘corretta’ , tra una batteria di argomenti di input di function diverse) che funziona così bene.

Nota: in base alla progettazione, se non esiste un’estensione di file per la stringa di input specificata, restituisce semplicemente una stringa vuota "" , non un errore né un messaggio di errore.

Ci vogliono due argomenti:

  • Stringa: fileNameOrURL (autoesplicativo)

  • Booleano: showUnixDotFiles (se mostrare o meno i file che iniziano con un punto “.”)

Nota (2): Se ti piace il mio codice, assicurati di aggiungerlo alla tua libreria js e / o repository, perché ho lavorato duramente per perfezionarlo, e sarebbe un peccato sprecare. Quindi, senza ulteriori indugi, eccolo qui:

 function getFileExtension(fileNameOrURL, showUnixDotFiles) { /* First, let's declare some preliminary variables we'll need later on. */ var fileName; var fileExt; /* Now we'll create a hidden anchor ('a') element (Note: No need to append this element to the document). */ var hiddenLink = document.createElement('a'); /* Just for fun, we'll add a CSS attribute of [ style.display = "none" ]. Remember: You can never be too sure! */ hiddenLink.style.display = "none"; /* Set the 'href' attribute of the hidden link we just created, to the 'fileNameOrURL' argument received by this function. */ hiddenLink.setAttribute('href', fileNameOrURL); /* Now, let's take advantage of the browser's built-in parser, to remove elements from the original 'fileNameOrURL' argument received by this function, without actually modifying our newly created hidden 'anchor' element.*/ fileNameOrURL = fileNameOrURL.replace(hiddenLink.protocol, ""); /* First, let's strip out the protocol, if there is one. */ fileNameOrURL = fileNameOrURL.replace(hiddenLink.hostname, ""); /* Now, we'll strip out the host-name (ie domain-name) if there is one. */ fileNameOrURL = fileNameOrURL.replace(":" + hiddenLink.port, ""); /* Now finally, we'll strip out the port number, if there is one (Kinda overkill though ;-)). */ /* Now, we're ready to finish processing the 'fileNameOrURL' variable by removing unnecessary parts, to isolate the file name. */ /* Operations for working with [relative, root-relative, and absolute] URL's ONLY [BEGIN] */ /* Break the possible URL at the [ '?' ] and take first part, to shave of the entire query string ( everything after the '?'), if it exist. */ fileNameOrURL = fileNameOrURL.split('?')[0]; /* Sometimes URL's don't have query's, but DO have a fragment [ # ](ie 'reference anchor'), so we should also do the same for the fragment tag [ # ]. */ fileNameOrURL = fileNameOrURL.split('#')[0]; /* Now that we have just the URL 'ALONE', Let's remove everything to the last slash in URL, to isolate the file name. */ fileNameOrURL = fileNameOrURL.substr(1 + fileNameOrURL.lastIndexOf("/")); /* Operations for working with [relative, root-relative, and absolute] URL's ONLY [END] */ /* Now, 'fileNameOrURL' should just be 'fileName' */ fileName = fileNameOrURL; /* Now, we check if we should show UNIX dot-files, or not. This should be either 'true' or 'false'. */ if ( showUnixDotFiles == false ) { /* If not ('false'), we should check if the filename starts with a period (indicating it's a UNIX dot-file). */ if ( fileName.startsWith(".") ) { /* If so, we return a blank string to the function caller. Our job here, is done! */ return ""; }; }; /* Now, let's get everything after the period in the filename (ie the correct 'file extension'). */ fileExt = fileName.substr(1 + fileName.lastIndexOf(".")); /* Now that we've discovered the correct file extension, let's return it to the function caller. */ return fileExt; }; 

Godere! Sei abbastanza benvenuto !:

Se hai a che fare con gli URL web, puoi usare:

 function getExt(filename){ return filename.split('.').pop().split("?")[0].split("#")[0]; } getExt("logic.v2.min.js") // js getExt("http://example.net/site/page.php?id=16548") // php getExt("http://example.net/site/page.html#welcome") // html 

Demo: https://jsfiddle.net/squadjot/q5ard4fj/

 fetchFileExtention(fileName) { return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2); } 
 var filetypeArray = (file.type).split("/"); var filetype = filetypeArray[1]; 

Questo è un approccio migliore.

In node.js, questo può essere ottenuto con il seguente codice:

 var file1 ="50.xsl"; var path = require('path'); console.log(path.parse(file1).name); 
 var file = "hello.txt"; var ext = (function(file, lio) { return lio === -1 ? undefined : file.substring(lio+1); })(file, file.lastIndexOf(".")); // hello.txt -> txt // hello.dolly.txt -> txt // hello -> undefined // .hello -> hello 

Preferisco usare lodash per la maggior parte delle cose quindi ecco una soluzione:

 function getExtensionFromFilename(filename) { let extension = ''; if (filename > '') { let parts = _.split(filename, '.'); if (parts.length >= 2) { extension = _.last(parts); } return extension; }