Comment obtenir des extensions de fichier avec JavaScript?

502

Voir le code:

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

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

Réponses:

796

Édition plus récente: Beaucoup de choses ont changé depuis la publication initiale de cette question - il y a beaucoup de très bonnes informations dans la réponse révisée de wallacer ainsi que l'excellente ventilation de VisioN


Edit: Tout simplement parce que c'est la réponse acceptée; la réponse de wallacer est en effet bien meilleure:

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;
Tom
la source
1
N'est-il pas coûteux d'exécuter l'expression régulière deux fois?
Andrew Hedges,
5
La réponse très appréciée ci-dessous est bien meilleure.
fletom
2
Malheureusement, les deux solutions échouent pour des noms comme fichier et .htaccess .
VisioN du
3
Tous les cas possibles sont traités comme suit: return filename.split ("."). Slice (1) .pop () || "";
JustAndrei
1
@JustAndrei Toujours pas tous :) Pour un nom de fichier pur (nom de base?), Pas un chemin, pour des raisons pratiques, je pense que cela devrait être return filename.substring(0,1) === '.' ? '' : filename.split('.').slice(1).pop() || '';Cela prend également en charge le .filetype de fichiers (Unix caché, je crois) aussi. C'est si vous voulez le garder comme une doublure, ce qui est un peu désordonné à mon goût.
kooker le
833
return filename.split('.').pop();

Rester simple :)

Éditer:

Ceci est une autre solution non regex qui, je pense, est plus efficace:

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

Il y a quelques cas de coin qui sont mieux traités par la réponse de VisioN ci-dessous, en particulier les fichiers sans extension ( .htaccessetc. inclus).

Il est très performant et gère les cas d'angle 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 pas de chaîne avant le point. C'est une solution très bien conçue, bien que difficile à lire. Collez-le dans votre bibliothèque d'aide et utilisez-le.

Ancien montage:

Une implémentation plus sûre si vous allez exécuter 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 dans ce sens

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.lengthc'est un, c'est un fichier visible sans extension c'est-à-dire. fichier

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

J'espère que cela aide à 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, pour la plupart des utilisations courantes, ce code devrait être parfaitement utilisable.

wallacer
la source
4
Je ne peux pas commenter la performance, mais celle-ci a certainement l'air propre! Je l'utilise. +1
pc1oad1etter
6
mais dans ce cas, le nom du fichier ressemble à filname.tes.test.jpg. Veuillez considérer la sortie. J'espère que ce sera faux.
Fero
19
dans ce cas, la sortie est "jpg"
wallacer
1
Brillant! Merci beaucoup. C'est agréable de voir une solution n'utilisant pas l'expression régulière; Je l'ai fait avec PHP et il n'utilise que quelques fonctions. +1
Bojangles
3
@wallacer: que se passe-t-il si filenameaucune extension n'est disponible? Cela ne retournerait-il pas simplement le nom de fichier de base, ce qui serait un peu mauvais?
Nicol Bolas
288

La solution suivante est rapide et suffisamment courte pour être utilisée dans des opérations en bloc et économiser des octets supplémentaires:

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

Voici une autre solution universelle non regexp d'une ligne:

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

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

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

Si vous vous souciez de la vitesse, vous pouvez exécuter la référence et vérifier que les solutions fournies sont les plus rapides, tandis que la courte est extrêmement rapide:

Comparaison de vitesse

Comment fonctionne le court:

  1. String.lastIndexOfretourne la dernière position de la sous-chaîne (ie ".") dans la chaîne donnée (ie fname). Si la sous-chaîne n'est pas trouvée, la méthode retourne -1.
  2. Les positions "inacceptables" du point dans le nom de fichier sont -1et 0, qui se réfèrent respectivement aux noms sans extension (par exemple "name") et aux noms commençant par un point (par exemple ".htaccess").
  3. L'opérateur de décalage vers la droite de remplissage zéro ( >>>) s'il est utilisé avec zéro affecte les nombres négatifs se transformant -1en 4294967295et -2vers 4294967294, ce qui est utile pour garder le nom de fichier inchangé dans les cas de bord (une sorte d'astuce ici).
  4. String.prototype.sliceextrait la partie du nom de fichier de la position qui a été calculée comme décrit. Si le numéro de position est supérieur à la longueur de la méthode de chaîne renvoyée "".

Si vous voulez une solution plus claire qui fonctionnera de la même manière (plus avec un support supplémentaire du chemin complet), vérifiez la version étendue suivante. Cette solution sera plus lente que les monolignes précédentes mais 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.

Vision
la source
5
Ne marche pas. "/home/user/.app/config" renvoie "app / config", ce qui est totalement faux.
mrbrdo
34
@mrbrdo Cette méthode n'est pas censée fonctionner avec le chemin complet uniquement avec les noms de fichiers, comme demandé par la question. Lisez attentivement la question avant de voter.
VisioN
8
Pourquoi faire des efforts pour optimiser une ligne de code aussi triviale? Les opérateurs Tilde et bitshift sont si rarement vus en JavaScript que je ne peux pas supporter une telle réponse. S'il faut 5 puces pour expliquer le fonctionnement d'une ligne de code, mieux vaut réécrire le code pour qu'il soit réellement compréhensible.
Jackson
6
La vitesse de cette ligne ne fera aucune différence perceptible dans n'importe quelle application. Bitwise est si rarement utilisé que les linters populaires comme JSLint et JSHint mettent en garde contre leur utilisation. L'obsession des performances et de la compacité de cette logique a dégradé la qualité du code; si le code nécessite une «enquête supplémentaire», je le considère comme «mauvais».
Jackson
10
@Jackson Considérant qu'il s'agit d'un site pour offrir plusieurs solutions à un problème, avoir une solution qui optimise les performances n'est jamais une mauvaise chose. Votre déclaration "ne fera aucune différence perceptible dans n'importe quelle application" est entièrement basée sur l'étendue de vos applications possibles dans lesquelles cela pourrait être utilisé. autre code dont ils ont besoin pour créer une application informatique intensive qu'ils écrivent.
nrylee
33
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")
PhiLho
la source
Pour le faire fonctionner dans IE: var pattern = "^. + \\. ([^.] +) $"; var ext = new RegExp (modèle);
spc16670
20
function getExt(filename)
{
    var ext = filename.split('.').pop();
    if(ext == filename) return "";
    return ext;
}
Dima
la source
8
retourner (ext === nom de fichier)? '': ext;
Michiel
13
var extension = fileName.substring(fileName.lastIndexOf('.')+1);
Pono
la source
8
var parts = filename.split('.');
return parts[parts.length-1];
Randy Sugianto «Yuku»
la source
8
function file_get_ext(filename)
    {
    return typeof filename != "undefined" ? filename.substring(filename.lastIndexOf(".")+1, filename.length).toLowerCase() : false;
    }
Joe Scylla
la source
8

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

Tester

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.

Jack
la source
7

Rapide et fonctionne correctement avec les chemins

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

Quelques cas de bord

/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 marginaux.

mrbrdo
la source
Quels cas marginaux voulez-vous dire? Veuillez consulter ma solution ici: stackoverflow.com/a/12900504/1249581 . Il fonctionne très bien dans tous les cas et beaucoup plus rapidement que tout regex.
VisioN
J'ai déjà répertorié les cas de bord. Et votre solution ne les gère pas correctement. Comme je l'ai déjà écrit, essayez "/dir.with.dot/file". Votre code renvoie "point / fichier", ce qui est ridiculement faux.
mrbrdo
1
Personne n'a demandé à analyser le chemin d'accès. La question portait sur l'extraction d'extensions des noms de fichiers.
VisioN
3
Comme je vous l'ai déjà dit, cela n'a jamais été dit explicitement, et une solution qui gère les chemins est évidemment beaucoup plus utile. La réponse à une question sur SO est censée être utile à d'autres personnes que la personne qui a posé la question. Je ne pense vraiment pas qu'une solution qui gère un sur-ensemble d'entrées doive être rétrogradée.
mrbrdo
3
Le downvote était pour l'utilisation de la variable globale avec .exec(). Votre code sera meilleur au fur et à mesure (filename.match(/[^\\/]\.([^\\/.]+)$/) || [null]).pop().
VisioN du
6

je voulais juste partager cela.

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

bien que cela ait pour inconvénient que les fichiers sans extension renverront la dernière chaîne. mais si vous le faites, cela résoudra tout:

   function getExtention(fileName){
     var i = fileName.lastIndexOf('.');
     if(i === -1 ) return false;
     return fileName.slice(i)
   }
Hussein Nazzal
la source
Autant que je me souvienne, la sliceméthode fait référence aux tableaux plutôt qu'aux chaînes. Pour les chaînes substrou substringfonctionnera.
VisioN
@VisioN mais je suppose que vous devez savoir qu'il y a String.prototype.sliceet aussi une Array.prototype.slicesorte de méthode pour les deux méthodes de travail
Hussein Nazzal
1
Ah oui. Tu as raison. J'ai complètement oublié cette méthode. Ma faute.
VisioN
5

Je suis sûr que quelqu'un pourra et va minimiser et / ou optimiser mon code à l'avenir. Mais, en ce moment , je suis à 200% confiant que mon code fonctionne dans toutes les situations uniques (par exemple, uniquement avec le nom de fichier uniquement , avec des URL relatives , relatives à la racine et absolues , avec des # balises de fragment , avec des ? chaînes de requête , etc.) sinon vous pouvez décider de vous lancer dessus), parfaitement et avec une précision extrême.

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

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

Ne pas être trop confiant ou souffler ma propre trompette, mais je n'ai vu aucun bloc de code pour cette tâche (trouver l' extension de fichier `` correcte '' , au milieu d'une batterie d' functionarguments d'entrée différents ) qui fonctionne aussi bien que cela.

Remarque: Par 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 (auto-explicatif)

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

Remarque (2): Si vous aimez mon code, assurez-vous de l'ajouter à votre bibliothèque js et / ou repo, car j'ai travaillé dur pour le perfectionner, et ce serait dommage de le gaspiller. Donc, sans plus tarder, 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!:

James Anderson Jr.
la source
1
Impressionnant. Merci!
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"));

山 茶树 和 葡萄 树
la source
5

Si vous avez affaire à des URL Web, vous pouvez utiliser:

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

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

Jakob Sternberg
la source
J'aime vraiment ta solution. Il en fait tellement avec si peu. Je vais l'utiliser.
Jules Manson
4

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;
}
Edward
la source
3
return filename.replace(/\.([a-zA-Z0-9]+)$/, "$1");

edit: Étrangement (ou peut-être pas) le $1dans le deuxième argument de la méthode replace ne semble pas fonctionner ... Désolé.

p4bl0
la source
1
Cela fonctionne parfaitement, mais vous avez manqué de devoir supprimer tout le reste du contenu de la chaîne: return filename.replace (/^.*? \. ([A-zA-Z0-9] +) $ /, "$ 1");
roenving
3

Je viens de réaliser qu'il ne suffit pas de mettre un commentaire sur la réponse de p4bl0, bien que la réponse de Tom résout clairement le problème:

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

Pour la plupart des applications, un script simple tel que

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

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

image.jpg?foo=bar

Il peut être un peu exagéré, mais je suggérerais d'utiliser un analyseur d'URL tel que celui-ci pour éviter l'échec en raison de noms de fichiers imprévisibles.

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

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

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

Justin Bull
la source
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");
  }
}
Jim Blackler
la source
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;
}

//usage

extension ('file.jpeg')

renvoie toujours la casse d'extension inférieure afin que vous puissiez la vérifier sur les travaux de changement de champ pour:

file.JpEg

fichier (sans extension)

fichier. (sans extension)

Jim Blackler
la source
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

Jenny O'Reilly
la source
1
La beauté vient avec la simplicité. C'est la réponse la plus intelligente, la plus élégante et la plus efficace de toutes. J'ai toujours utilisé String.substr (-3) ou String.substr (-4) pour récupérer les extensions sur les systèmes Windows. Pourquoi quelqu'un voudrait-il utiliser des expressions régulières et des boucles folles pour cela?
asiby
13
@asiby Ce type de solutions est la principale raison du crash des fusées spatiales après leur lancement.
VisioN du
3

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>

DzSoundNirvana
la source
3

Il existe une fonction de bibliothèque standard pour cela dans le pathmodule:

import path from 'path';

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

Production:

.SMS

Donc, si vous ne voulez que le format:

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

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

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

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

Il n'y a aucune raison de diviser des chaînes ou de regex.

sdgfsdh
la source
Qui a dit quelque chose sur le nœud?
Shannon Hochkins
Votre argument pour ne pas utiliser de fractionnement ou d'expressions régulières est d'inclure un plugin ou de regrouper l'application avec un nœud, c'est une réponse
exagérée
@ShannonHochkins la plupart du temps, ces choses sont configurées de toute façon
sdgfsdh
@AndreiDraganescu Je n'avais pas l'intention que cela soit condescendant, alors je l'ai atténué.
sdgfsdh
3

"one-liner" pour obtenir le nom de fichier et l'extension en utilisant reduceet la déstructuration des tableaux :

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


console.log({filename, extension});

// {
//   "filename": "filename.with_dot",
//   "extension": "png"
// }
boehm_s
la source
Cela ne fonctionne pas dans IE 11
Gokul Maha
Vous pouvez utiliser babel / typescript / polyfills pour les fonctionnalités ES7 + manquantes d'IE 11
boehm_s
2

Une solution d'une seule ligne qui tiendra également compte des paramètres de requête et des caractères dans 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
Labithiotis
la source
(1) Si un fichier n'a pas d'extension, cela renverra toujours le nom du fichier. (2) S'il y a un fragment dans l'URL, mais pas de requête (par exemple page.html#fragment), cela renverra l'extension de fichier et le fragment.
Jack
2

Cette solution simple

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

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

Vitim.us
la source
1

La réponse de Wallacer est agréable, 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 qui n'est pas bonne.

Essaye celui-là:

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

N'oubliez pas que certains fichiers ne peuvent pas avoir d'extension, donc:

var parts = filename.split('.');
return (parts.length > 1) ? parts.pop() : '';
Tamás Pap
la source
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
NSD
la source
1
fetchFileExtention(fileName) {
    return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2);
}
GauRang Omar
la source
2
Bien que cet extrait de code puisse résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question des lecteurs à l'avenir et que ces personnes ne connaissent peut-être pas les raisons de votre suggestion de code.
Brett DeWoody