web-dev-qa-db-fra.com

Comment puis-je obtenir des extensions de fichier avec JavaScript?

Voir le code: 

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

function getFileExtension(filename) {
    /*TODO*/
}
398
Sergio del Amo

Nouvelle édition: Beaucoup de choses ont changé depuis la publication de cette question - il y a beaucoup d'informations vraiment bonnes dans la réponse révisée de wallacer ainsi que l'excellente ventilation de VisioN


Edit: Juste parce que c'est la réponse acceptée; La réponse de wallacer est en effet beaucoup mieux:

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

Mon ancienne réponse:

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

Devrait le faire.

Edit: En réponse au commentaire de PhiLho, utilisez quelque chose comme:

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

Rester simple :) 

Modifier:

Ceci est une autre solution non regex qui, à mon avis, est plus efficace:

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

La réponse de VisioN ci-dessous permet de mieux gérer certains cas particuliers, en particulier les fichiers sans extension (.htaccess etc inclus).

Il est très performant et gère sans doute mieux les cas de coin en renvoyant "" au lieu de la chaîne complète quand il n’ya pas de point ou pas de chaîne avant le point. C'est une solution très bien conçue, mais difficile à lire. Collez-le dans votre aide lib et utilisez-le.

Ancien Edit:

Une implémentation plus sûre si vous rencontrez des fichiers sans extension, ou des fichiers cachés sans extension (voir le commentaire de VisioN à la réponse de Tom ci-dessus) correspond à cela.

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

Si a.length est un, c'est un fichier visible sans extension, c'est-à-dire. fichier

Si a[0] === "" et a.length === 2 c'est un fichier caché sans extension c'est-à-dire. .htaccess

J'espère que cela aidera à résoudre les problèmes avec les cas légèrement plus complexes. En termes de performances, je pense que cette solution est un peu plus lente que regex dans la plupart des navigateurs. Cependant, dans la plupart des cas, ce code devrait être parfaitement utilisable.

722
wallacer

La solution suivante est fast et short suffisants pour des opérations en bloc et pour sauvegarder des octets supplémentaires:

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

Voici une autre solution universelle non rationnelle à une ligne:

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

Les deux fonctionnent correctement avec des noms sans extension (par exemple myfile) ou commençant par . point (par exemple .htaccess):

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

Si vous tenez à la vitesse, vous pouvez lancer benchmark et vérifier que les solutions fournies sont les plus rapides, tandis que la solution courte est extrêmement rapide:

Speed comparison

_ {Comment le court fonctionne:} _

  1. String.lastIndexOf méthode retourne la dernière position de la sous-chaîne (i.e. ".") dans la chaîne donnée (i.e. fname). Si la sous-chaîne n'est pas trouvée, la méthode retourne -1.
  2. Les positions "inacceptables" de dot dans le nom de fichier sont -1 et 0, qui désignent respectivement les noms sans extension (par exemple "name") et les noms commençant par un point (par exemple ".htaccess").
  3. L'opérateur de décalage à droite rempli de zéro (>>>), s'il est utilisé avec zéro, affecte les nombres négatifs en transformant -1 en 4294967295 et -2 en 4294967294, ce qui est utile pour laisser le nom de fichier inchangé dans les cas Edge (une sorte de truc ici).
  4. String.prototype.slice extrait la partie du nom de fichier de la position calculée de la manière décrite. Si le numéro de position est supérieur à la longueur de la chaîne, la méthode retourne "".

Si vous souhaitez une solution plus claire qui fonctionnera de la même manière (avec un support supplémentaire du chemin complet), vérifiez la version étendue suivante. Cette solution sera plus lente _ que les précédentes, mais elle est beaucoup plus facile à comprendre.

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"

Les trois variantes doivent fonctionner dans n'importe quel navigateur Web côté client et peuvent également être utilisées dans le code NodeJS côté serveur.

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

Testé avec 

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

Également 

"a.b.c.d" (=> "d")
".a.b"    (=> "b")
"a..b"    (=> "b")
23
PhiLho
function getExt(filename)
{
    var ext = filename.split('.').pop();
    if(ext == filename) return "";
    return ext;
}
18
Dima
var extension = fileName.substring(fileName.lastIndexOf('.')+1);
12
Pono

Code

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

Notez qu'en l'absence d'une requête, le fragment peut toujours être présent.

"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 Avertissements.

8
Jack
function file_get_ext(filename)
    {
    return typeof filename != "undefined" ? filename.substring(filename.lastIndexOf(".")+1, filename.length).toLowerCase() : false;
    }
8
Joe Scylla
var parts = filename.split('.');
return parts[parts.length-1];
8

Rapide et fonctionne correctement avec les chemins

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

Quelques cas Edge

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

Les solutions utilisant la division sont lentes et les solutions avec lastIndexOf ne gèrent pas les cas Edge.

6
mrbrdo

Essaye ça:

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

je voulais juste partager ceci.

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

bien que cela cause un inconvénient: les fichiers sans extension renverront la dernière chaîne .

   function getExtention(fileName){
     var i = fileName.lastIndexOf('.');
     if(i === -1 ) return false;
     return fileName.slice(i)
   }
4
Hussein Nazzal
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
Mani

Je viens de me rendre compte qu'il ne suffit pas de commenter la réponse de p4bl0, même si la réponse de Tom résout clairement le problème:

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

Je suis beaucoup de lunes en retard à la fête mais pour plus de simplicité j'utilise quelque chose comme ça

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
DzSoundNirvana

Pour la plupart des applications, un script simple tel que 

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

fonctionnerait très bien (comme prévu par Tom). Cependant, cela n’est pas infaillible. Cela ne fonctionne pas si le nom de fichier suivant est fourni:

image.jpg?foo=bar

C'est peut-être un peu excessif, mais je suggérerais d'utiliser un analyseur d'URL tel que celui-ci pour éviter les erreurs dues à des noms de fichiers imprévisibles.

En utilisant cette fonction particulière, vous pourriez obtenir le nom du fichier comme ceci:

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

Cela produira "image.jpg" sans les vars url. Ensuite, vous êtes libre de saisir l'extension de fichier.

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

edit: Étrangement (ou peut-être que ce n'est pas le cas), le $1 dans le deuxième argument de la méthode de remplacement ne semble pas fonctionner ... Désolé.

3
p4bl0

// 获取文件后缀名
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"));

3

Si vous recherchez une extension spécifique et connaissez sa longueur, vous pouvez utiliser substr:

var file1 = "50.xsl";

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

Référence JavaScript:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr

3
Jenny O'Reilly
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;
}

//usage

extension ('fichier.jpeg')

retourne toujours l'extension minuscule afin que vous puissiez le vérifier en cas de changement de champ.

file.JpEg

fichier (pas d'extension)

fichier. (noextension)

3
gafhus

Une solution à une ligne qui tiendra également compte des paramètres de requête et de tous les caractères de l’URL.

string.match(/(.*)\??/i).shift().replace(/\?.*/, '').split('.').pop()

// Example
// some.url.com/with.in/&ot.s/files/file.jpg?spec=1&.ext=jpg
// jpg
2
Labithiotis
fetchFileExtention(fileName) {
    return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2);
}
1
GauRang Omar

Je suis sûr que quelqu'un peut et va minimiser et/ou optimiser mon code à l'avenir. Mais, à partir de maintenant, je suis à 200% sûr que mon code fonctionne dans toutes les situations (par exemple, juste avec le nom de fichier uniquement, avec relatif, parent relative, et absolu URL, avec les balises fragment#, avec les chaînes requête?, et tout ce que vous pourriez décider de lancer. à elle), sans faille et avec une précision de pointe. 

Pour preuve, visitez: https://projects.jamesandersonjr.com/web/js_projects/get_file_extension_test.php

Voici le JSFiddle: https://jsfiddle.net/JamesAndersonJr/ffcdd5z3/

Ne pas trop me fier à moi-même ni faire exploser ma propre trompette, mais je n’ai pas vu le bloc de code aucun pour cette tâche (recherche de l’extension de fichier 'correcte', au milieu d’une batterie de function arguments d’entrée) qui fonctionne aussi bien que cela.

Remarque: De par sa conception, si une extension de fichier n'existe pas pour la chaîne d'entrée donnée, elle renvoie simplement une chaîne vide "", pas une erreur ni un message d'erreur.

Il faut deux arguments:

  • String: fileNameOrURL _ ​​(explicite)

  • Boolean: showUnixDotFiles (Indique ou non les fichiers commençant par un point ".")

Note (2): Si vous aimez mon code, assurez-vous de l'ajouter à votre bibliothèque js, et/ou à votre référentiel, car j'ai travaillé dur pour le perfectionner, et il serait dommage de perdre. Alors, sans plus tarder, le voici:

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

Prendre plaisir! De rien!:

1
James Anderson Jr.

Si vous traitez avec des URL Web, vous pouvez utiliser:

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

Démo: https://jsfiddle.net/squadjot/q5ard4fj/

1
Jakob Sternberg

Cette solution simple

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

Des tests

/* 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
Vitim.us

Il existe une fonction de bibliothèque standard pour cela dans le module path

import path from 'path';

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

Sortie: 

.SMS

Donc, si vous voulez seulement le format: 

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

S'il n'y a pas d'extension, alors la fonction retournera une chaîne vide: 

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

Si vous utilisez Node, alors path est intégré. Si vous ciblez le navigateur, Webpack vous proposera une implémentation path. Si vous ciblez le navigateur sans Webpack, vous pouvez inclure path-browserify manuellement. 

Il n'y a aucune raison de scinder ou de regex. 

1
sdgfsdh

N'oubliez pas que certains fichiers ne peuvent avoir aucune extension, alors:

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

La réponse de Wallacer est Nice, mais une vérification supplémentaire est nécessaire.

Si le fichier n'a pas d'extension, il utilisera le nom de fichier comme extension, ce qui n'est pas bien.

Essaye celui-là:

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

"one-liner" pour obtenir le nom du fichier et son extension en utilisant reduce et array destructuring

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

avec une meilleure indentation:

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('.')], [])


// {
//   "filename": "filename.with_dot",
//   "extension": "png"
// }
0
boehm_s
var filetypeArray = (file.type).split("/");
var filetype = filetypeArray[1];

C'est une meilleure approche imo. 

0
Chathuranga

Je préfère utiliser lodash pour la plupart des choses, alors voici une solution:

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

Dans node.js, cela peut être réalisé avec le code suivant:

var file1 ="50.xsl";
var path = require('path');
console.log(path.parse(file1).name);
0
Jibesh Patra
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
0
NSD