Come posso ottenere estensioni di file con JavaScript?


502

Vedi codice:

var file1 = "50.xsl";
var file2 = "30.doc";
getFileExtension(file1); //returns xsl
getFileExtension(file2); //returns doc

function getFileExtension(filename) {
    /*TODO*/
}

Risposte:


796

Più recente modifica: Un sacco di cose sono cambiate da quando la questione è stata inizialmente pubblicato - c'è un sacco di veramente buone informazioni in risposta rivisto wallacer così come 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;

1
Non è costoso eseguire il regex due volte?
Andrew Hedges,

5
La risposta molto apprezzata di seguito è molto meglio.
fletom,

2
Sfortunatamente entrambe le soluzioni falliscono per nomi come file e .htaccess .
VisioN,

3
Tutti i casi possibili vengono elaborati come segue: return nomefile.split ("."). Slice (1) .pop () || "";
JustAndrei,

1
@JustAndrei Ancora non tutti :) Per puro nome di file (basename?), Non un percorso, per motivi pratici, penso che dovrebbe essere return filename.substring(0,1) === '.' ? '' : filename.split('.').slice(1).pop() || '';Questo si occupa anche di .file(Unix nascosto, credo) tipo di file. Cioè se vuoi tenerlo come una linea, che è un po 'disordinato per i miei gusti.
kooker,

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

Mantienilo semplice :)

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 angolari che sono meglio gestiti dalla risposta di VisioN di seguito, in particolare i file senza estensione ( .htaccessecc. Incluso).

È molto performante e gestisce i casi angolari in modo probabilmente migliore restituendo ""invece la stringa completa quando non c'è punto o nessuna stringa prima del punto. È una soluzione molto ben realizzata, sebbene difficile da leggere. Inseriscilo nella tua libreria di helper e usalo.

Vecchia modifica:

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

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, ad es. file

Se a[0] === ""ed a.length === 2è un file nascosto senza estensione ie. .htaccess

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


4
Non posso commentare la performance, ma questo sembra sicuramente pulito! Lo sto usando. +1
pc1oad1etter

6
ma in questo caso il nome del file sembra filname.tes.test.jpg. Si prega di considerare l'output. Spero che sia falso.
Fero,

19
in tal caso l'output è "jpg"
wallacer,

1
Brillante! Grazie mille. È bello vedere una soluzione che non usa regex; L'ho fatto con PHP e utilizza solo un paio di funzioni. +1
Bojangles,

3
@wallacer: cosa succede se in filenamerealtà non ha un'estensione? Questo non restituirebbe semplicemente il nome file di base, che sarebbe un pò cattivo?
Nicol Bolas,

288

La seguente soluzione è abbastanza veloce e breve da utilizzare in operazioni in blocco e salvare byte extra:

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

Ecco un'altra soluzione universale non regexp a una riga:

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

Entrambi funzionano correttamente con nomi che non hanno estensione (ad esempio myfile ) o che iniziano con un .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 verificare che le soluzioni fornite siano le più veloci, mentre quella corta è tremendamente veloce:

Confronto di velocità

Come funziona quello corto:

  1. String.lastIndexOfIl metodo restituisce l'ultima posizione della sottostringa (ie ".") nella stringa specificata (ie fname). Se la sottostringa non viene trovata, viene restituito il metodo -1.
  2. Le posizioni "inaccettabili" del punto nel nome del file sono -1e 0, che si riferiscono rispettivamente ai nomi senza estensione (ad es. "name") E ai nomi che iniziano con il punto (ad es ".htaccess".).
  3. L'operatore di spostamento a destra con riempimento>>> a zero ( ) se utilizzato con zero influisce sui numeri negativi che si trasformano -1in 4294967295e -2in 4294967294, il che è utile per mantenere invariato il nome del file nei casi limite (una sorta di trucco qui).
  4. String.prototype.sliceestrae la parte del nome file dalla posizione calcolata come descritto. Se il numero di posizione è superiore alla lunghezza del metodo stringa restituito "".

Se si desidera una soluzione più chiara che funzionerà allo stesso modo (più con il supporto aggiuntivo del percorso completo), controllare la seguente versione estesa. Questa soluzione sarà più lenta delle precedenti linee guida, 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.


5
Non funziona. "/home/user/.app/config" restituisce "app / config", che è totalmente sbagliato.
mrbrdo,

34
@mrbrdo Questo metodo non dovrebbe funzionare con il percorso completo solo con i nomi dei file, come richiesto dalla domanda. Leggi attentamente la domanda prima di effettuare il downgrade.
VisioN,

8
Perché fare di tutto per ottimizzare una linea di codice così banale? Gli operatori Tilde e bitshift sono così raramente visti in JavaScript che non posso supportare una risposta del genere. Se ci vogliono 5 punti elenco per spiegare come funziona 1 riga di codice, meglio riscrivere il codice in modo che sia effettivamente comprensibile.
Jackson,

6
La velocità di questa linea non farà alcuna differenza percettibile in qualsiasi applicazione. Bitwise è così raramente usato che linters popolari come JSLint e JSHint mettono in guardia contro il loro utilizzo. L'ossessione per le prestazioni e la compattezza di questa logica ha degradato la qualità del codice; se il codice richiede "ulteriori indagini", lo considero "negativo".
Jackson,

10
@Jackson Considerando che questo è un sito per offrire molteplici soluzioni a un problema, avere una soluzione che ottimizza le prestazioni non è mai una cosa negativa. La tua affermazione "non farà alcuna differenza percepibile in qualsiasi applicazione" è completamente basata sul tuo ambito ristretto di possibili applicazioni in cui potrebbe essere utilizzato. Oltre a ciò, può fornire a qualcuno che guarda al problema un'esperienza di apprendimento in cui può ottimizzare alcune altro codice necessario per creare un'applicazione ad alta intensità di elaborazione che stanno scrivendo.
nrylee,

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

Testato con

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

Anche

"a.b.c.d" (=> "d")
".a.b"    (=> "b")
"a..b"    (=> "b")

Per farlo funzionare in IE: var pattern = "^. + \\. ([^.] +) $"; var ext = new RegExp (modello);
spc16670,

20
function getExt(filename)
{
    var ext = filename.split('.').pop();
    if(ext == filename) return "";
    return ext;
}

8
return (ext === nomefile)? '': ext;
Michiel,

13
var extension = fileName.substring(fileName.lastIndexOf('.')+1);


8
function file_get_ext(filename)
    {
    return typeof filename != "undefined" ? filename.substring(filename.lastIndexOf(".")+1, filename.length).toLowerCase() : false;
    }

8

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                                                                        --> ""
"a.b.c.d"                                                                   --> "d"
".a.b"                                                                      --> "b"
".a.b."                                                                     --> ""
"a...b"                                                                     --> "b"
"..."                                                                       --> ""

JSLint

0 avvisi.


7

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.


Quali casi limite intendi? Fare riferimento alla mia soluzione qui: stackoverflow.com/a/12900504/1249581 . Funziona bene in tutti i casi e molto più velocemente di qualsiasi regex.
VisioN,

Ho già elencato i casi limite. E la tua soluzione NON li gestisce correttamente. Come ho già scritto, prova "/dir.with.dot/file". Il tuo codice restituisce "punto / file" che è ridicolmente sbagliato.
mrbrdo,

1
Nessuno ha richiesto di analizzare il percorso. La domanda riguardava l'estrazione delle estensioni dai nomi dei file.
VisioN,

3
Come ti ho già detto, ciò non è mai stato detto esplicitamente e una soluzione che gestisce i percorsi è ovviamente molto più utile. La risposta a una domanda su SO dovrebbe essere utile ad altre persone oltre alla persona che ha posto la domanda. Non credo davvero che una soluzione che gestisca un superset di input debba essere sottoposta a downgrade.
mrbrdo,

3
Il downvote era per l'utilizzo della variabile globale con .exec(). Il tuo codice sarà migliore come (filename.match(/[^\\/]\.([^\\/.]+)$/) || [null]).pop().
VisioN,

6

volevo solo condividere questo.

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

sebbene ciò abbia un inconveniente, 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)
   }

Per quanto ricordo il slicemetodo si riferisce alle matrici piuttosto che alle stringhe. Per le stringhe substro substringfunzionerà.
VisioN,

@VisioN ma immagino che dovresti sapere che c'è String.prototype.slicee anche un Array.prototype.slicemodo in cui entrambi funzionano in un certo senso
Hussein Nazzal

1
Ah sì. Hai ragione. Dimenticato completamente questo metodo. Colpa mia.
VisioN,

5

Sono sicuro che qualcuno potrà, e lo farà, minimizzare e / o ottimizzare il mio codice in futuro. Ma al momento sono sicuro al 200% che il mio codice funziona in ogni situazione unica (ad es. Solo con il nome del file , con URL relativi , relativi alla radice e assoluti , con tag di frammenti # , con stringhe di query ? e quant'altro altrimenti potresti decidere di lanciarlo), in modo impeccabile e con estrema precisione.

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

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

Non essere troppo sicuro di me, o suonare la mia tromba, ma non ho visto nessun blocco di codice per questo compito (trovare l' estensione del file 'corretta' , in mezzo a una batteria di diversi functionargomenti di input) che funzioni così come questo.

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 (Indica 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 repo, perché ho lavorato sodo 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 (i.e. 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 [ # ](i.e '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 (i.e. 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 il benvenuto !:


1
Eccezionale. Grazie!
GollyJer,

5

// 获取文件后缀名
function getFileExtension(file) {
  var regexp = /\.([0-9a-z]+)(?:[\?#]|$)/i;
  var extension = file.match(regexp);
  return extension && extension[1];
}

console.log(getFileExtension("https://www.example.com:8080/path/name/foo"));
console.log(getFileExtension("https://www.example.com:8080/path/name/foo.BAR"));
console.log(getFileExtension("https://www.example.com:8080/path/name/.quz/foo.bar?key=value#fragment"));
console.log(getFileExtension("https://www.example.com:8080/path/name/.quz.bar?key=value#fragment"));


5

Se hai a che fare con URL web, puoi utilizzare:

function getExt(filepath){
     return filepath.split("?")[0].split("#")[0].split('.').pop();
}

getExt("../js/logic.v2.min.js") // js
getExt("http://example.net/site/page.php?id=16548") // php
getExt("http://example.net/site/page.html#welcome.to.me") // html
getExt("c:\\logs\\yesterday.log"); // log

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


Mi piace molto la tua soluzione. Fa così tanto con così poco. Lo userò.
Jules Manson,

4

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

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

modifica: Stranamente (o forse non lo è) il $1secondo argomento del metodo di sostituzione non sembra funzionare ... Mi dispiace.


1
Funziona perfettamente, ma ti sei perso il fatto che dovrai rimuovere tutti gli altri contenuti della stringa: return filename.replace (/^.*? \. ([A-zA-Z0-9] +) $ /, "$ 1");
roenving,

3

Mi sono appena reso conto che non è sufficiente inserire un commento sulla risposta di p4bl0, sebbene la risposta di Tom risolva chiaramente il problema:

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

3

Per la maggior parte delle applicazioni, un semplice script come

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

funzionerebbe benissimo (come fornito da Tom). Tuttavia, questo non è a prova di errore. Non funziona se viene fornito il seguente nome file:

image.jpg?foo=bar

Potrebbe essere un po 'eccessivo, ma suggerirei di utilizzare un parser 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;

Questo produrrà "image.jpg" senza l'URL VAR. Quindi sei libero di prendere l'estensione del file.


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

3
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 cas inferiore in modo da poterlo verificare sul cambio di campo funziona per:

file.JpEg

file (nessuna estensione)

file. (Noextension)


3

Se stai cercando un'estensione specifica e conosci la sua 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


1
La bellezza arriva con semplicità. Questa è la risposta più intelligente, più elegante e più efficiente di tutte. Ho sempre usato String.substr (-3) o String.substr (-4) per afferrare estensioni su sistemi basati su Windows. Perché qualcuno dovrebbe voler usare espressioni regolari e loop folli per questo.
asiby,

13
@asiby Questo tipo di soluzioni è il motivo principale per cui i razzi spaziali si schiantano dopo il lancio.
VisioN,

3

Sono molte lune in ritardo alla 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;
<div id="showInMe"></div>


3

C'è una funzione di libreria standard per questo nel pathmodulo:

import path from 'path';

console.log(path.extname('abc.txt'));

Produzione:

.testo

Quindi, se vuoi solo il formato:

path.extname('abc.txt').slice(1) // 'txt'

Se non è presente alcuna estensione, la funzione restituirà una stringa vuota:

path.extname('abc') // ''

Se stai usando Node, allora pathè integrato. Se scegli come target il browser, Webpack raggrupperà pathun'implementazione per te. Se si sta prendendo di mira il browser senza Webpack, è possibile includere manualmente path-browserify .

Non vi è alcun motivo per eseguire la suddivisione delle stringhe o regex.


Chi ha detto qualcosa sul nodo?
Shannon Hochkins,

Il tuo argomento per non usare espressioni di divisione o regolari è quello di includere plugin o raggruppare l'applicazione con il nodo, è una risposta eccessiva per un'attività umile
Shannon Hochkins,

@ShannonHochkins la maggior parte delle volte hai comunque impostato queste cose
sdgfsdh

@AndreiDraganescu Non intendevo che fosse condiscendente, quindi l'ho attenuato.
sdgfsdh,

3

"one-liner" per ottenere nome file ed estensione usando reducee destrutturazione dell'array :

var str = "filename.with_dot.png";
var [filename, extension] = str.split('.').reduce((acc, val, i, arr) => (i == arr.length - 1) ? [acc[0].substring(1), val] : [[acc[0], val].join('.')], [])

console.log({filename, extension});

con migliore rientro:

var str = "filename.with_dot.png";
var [filename, extension] = str.split('.')
   .reduce((acc, val, i, arr) => (i == arr.length - 1) 
       ? [acc[0].substring(1), val] 
       : [[acc[0], val].join('.')], [])


console.log({filename, extension});

// {
//   "filename": "filename.with_dot",
//   "extension": "png"
// }

Questo non funziona in IE 11
Gokul Maha il

Puoi usare babel / dattiloscritto / polyfill per le funzionalità ES7 + mancanti di IE 11
boehm_s

2

Una soluzione a una riga che terrà conto anche dei parametri della query e di tutti i 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

(1) Se un file non ha estensione, questo restituirà comunque il nome del file. (2) Se nell'URL è presente un frammento, ma nessuna query (ad es. page.html#fragment), Verrà restituita l'estensione del file e il frammento.
Jack

2

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


1

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

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

Prova questo:

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

1

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

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

1
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

1
fetchFileExtention(fileName) {
    return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2);
}

2
Mentre questo frammento di codice può risolvere la domanda, inclusa una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro e che queste persone potrebbero non conoscere i motivi del tuo suggerimento sul codice.
Brett DeWoody,
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.