641 votes

Comment puis-je obtenir les extensions de fichiers 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*/
}

1050voto

Tom Points 1944

Nouvelle édition : Beaucoup de choses ont changé depuis que cette question a été initialement postée - il y a beaucoup de très bonnes informations dans Réponse révisée de Wallacer ainsi que L'excellente analyse de VisioN


Edit : Juste parce que c'est la réponse acceptée ; Réponse de wallacer est en effet bien meilleur :

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

Mon ancienne réponse :

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

Il faut le faire.

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

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

3 votes

N'est-il pas coûteux d'exécuter la regex deux fois ?

0 votes

Est-il préférable d'utiliser un regex plutôt que le lastindexof ? merci.

7 votes

La réponse ci-dessous, très bien notée, est bien meilleure.

1023voto

wallacer Points 4012
return filename.split('.').pop();

Edit :

Il s'agit d'une autre solution non-regex qui, à mon avis, est plus efficace :

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

Il y a certains cas particuliers qui sont mieux gérés par La réponse de VisioN ci-dessous, en particulier les fichiers sans extension ( .htaccess etc. inclus).

Elle est très performante, et gère les cas particuliers d'une manière sans doute meilleure en retournant "" au lieu de la chaîne complète lorsqu'il n'y a pas de point ou de chaîne avant le point. C'est une solution très bien conçue, bien que difficile à lire. Placez-la dans votre bibliothèque d'aides et utilisez-la.

Vieille édition :

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) serait quelque chose comme ceci

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] === "" y a.length === 2 c'est un fichier caché sans extension, c'est-à-dire. .htaccess

Cela devrait permettre de résoudre les problèmes liés aux cas un peu plus complexes. En termes de performances, je pense que cette solution est un peu plus lent que regex dans la plupart des navigateurs. Toutefois, pour les usages les plus courants, ce code devrait être parfaitement utilisable.

4 votes

Je ne peux pas me prononcer sur les performances, mais celui-ci a l'air propre ! Je l'utilise. +1

6 votes

Mais dans ce cas, le nom du fichier ressemble à filname.tes.test.jpg. Veuillez considérer le résultat. J'espère qu'il sera faux.

21 votes

Dans ce cas, le résultat est "jpg".

361voto

VisioN Points 62518

La solution suivante est rapide y court suffisant pour être utilisé dans des opérations de masse et économiser des octets supplémentaires :

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

Voici une autre solution universelle non-regexp en une ligne :

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

Les deux fonctionnent correctement avec des noms n'ayant pas d'extension (par ex. monfichier ) ou commençant par . point (par exemple .htaccess ):

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

Si vous vous souciez de la vitesse, vous pouvez utiliser la fonction repère et vérifiez que les solutions fournies sont les plus rapides, tandis que la solution courte est extrêmement rapide :

Speed comparison

Comment fonctionne le court-circuit :

  1. String.lastIndexOf renvoie la dernière position de la sous-chaîne (c'est-à-dire que la méthode "." ) dans la chaîne de caractères donnée (c'est-à-dire fname ). Si la sous-chaîne n'est pas trouvée, la méthode renvoie -1 .
  2. Les positions "inacceptables" du point dans le nom de fichier sont les suivantes -1 y 0 qui se réfèrent respectivement à des noms sans extension (par ex. "name" ) et aux noms qui commencent par un point (par ex. ".htaccess" ).
  3. Opérateur de l'équipe de droite à effectif réduit ( >>> ) s'il est utilisé avec zéro affecte les nombres négatifs transformant -1 a 4294967295 y -2 a 4294967294 qui est utile pour que le nom du fichier reste inchangé dans les cas limites (une sorte d'astuce ici).
  4. String.prototype.slice extrait la partie du nom du fichier à partir de la position qui a été calculée comme décrit. Si le numéro de position est supérieur à la longueur de la chaîne de caractères, la méthode retourne "" .

Si vous souhaitez une solution plus claire qui fonctionne de la même manière (avec en plus le support du chemin complet), consultez la version étendue suivante. Cette solution sera plus lent 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"

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

0 votes

@Zipp Afin de le rendre plus compréhensible, j'ai ajouté la description de l'approche et la comparaison de vitesse pour illustrer la rapidité de la solution.

0 votes

"fname.substr((~-fname.lastIndexOf(".") >>> 0) + 2)" donne une valeur erronée pour ".htaccess".

0 votes

@BennyNeugebauer Qu'est-ce qui ne va pas dans votre cas ? Cela donne "" depuis un nom de fichier qui commence par un point (comme .htaccess o .htpasswd ) n'a pas d'extension.

40voto

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

Testé avec

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

Aussi

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

0 votes

Pour le faire fonctionner dans IE : var pattern = "^.+ \\. ([^.]+)$" ; var ext = new RegExp(pattern) ;

24voto

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

8 votes

Return (ext===filename) ? '' : ext ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X