¿Cómo puedo obtener extensiones de archivo con JavaScript?

502

Ver código:

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

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

Respuestas:

796

Edición más reciente: Muchas cosas han cambiado desde que esta pregunta se publicó inicialmente: hay una gran cantidad de información realmente buena en la respuesta revisada de wallacer, así como en el excelente desglose de VisioN


Editar: solo porque esta es la respuesta aceptada; La respuesta de wallacer es mucho mejor:

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

Mi vieja respuesta:

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

Deberías hacerlo.

Editar: en respuesta al comentario de PhiLho, use algo como:

return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined;
Tom
fuente
1
¿No es costoso ejecutar la expresión regular dos veces?
Andrew Hedges
55
La respuesta altamente calificada a continuación es mucho mejor.
fletom
2
Desafortunadamente, ambas soluciones fallan para nombres como file y .htaccess .
VisioN
3
Todos los casos posibles se procesan de la siguiente manera: return filename.split ("."). Slice (1) .pop () || "";
JustAndrei
1
@JustAndrei Todavía no todo :) Para el nombre de archivo puro (¿nombre básico?), No es una ruta, por razones prácticas, creo que debería ser return filename.substring(0,1) === '.' ? '' : filename.split('.').slice(1).pop() || '';Esto también se encarga de .filelos archivos (Unix ocultos, creo). Eso es si quieres mantenerlo como una línea, lo cual es un poco desordenado para mi gusto.
kooker
833
return filename.split('.').pop();

Mantenlo simple :)

Editar:

Esta es otra solución no regex que creo que es más eficiente:

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

Hay algunos casos de esquina que se manejan mejor con la respuesta de VisioN a continuación, particularmente los archivos sin extensión ( .htaccessetc. incluidos).

Es muy eficaz y maneja los casos de esquina de una manera posiblemente mejor al regresar en ""lugar de la cadena completa cuando no hay punto o cadena antes del punto. Es una solución muy bien diseñada, aunque difícil de leer. Péguelo en su lib de ayuda y simplemente úselo.

Edición antigua:

Una implementación más segura si vas a encontrar archivos sin extensión, o archivos ocultos sin extensión (ver el comentario de VisioN a la respuesta de Tom más arriba) sería algo similar.

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.lengthes uno, es un archivo visible sin extensión, es decir. archivo

Si a[0] === ""y a.length === 2es un archivo oculto sin extensión, es decir. .htaccess

Espero que esto ayude a aclarar los problemas con los casos un poco más complejos. En términos de rendimiento, creo que esta solución es un poco más lenta que la expresión regular en la mayoría de los navegadores. Sin embargo, para los propósitos más comunes, este código debe ser perfectamente utilizable.

wallacer
fuente
44
No puedo comentar sobre el rendimiento, ¡pero este ciertamente se ve limpio! Lo estoy usando. +1
pc1oad1etter
66
pero en este caso el nombre del archivo se parece a filname.tes.test.jpg. Tenga en cuenta la salida. Espero que sea falso.
Fero
19
en ese caso la salida es "jpg"
wallacer
1
¡Brillante! Muchas gracias. Es bueno ver una solución que no usa expresiones regulares; He hecho esto con PHP y solo usa un par de funciones. +1
Bojangles
3
@wallacer: ¿Qué sucede si en filenamerealidad no tiene una extensión? ¿No devolvería esto simplemente el nombre de archivo base, que sería algo malo?
Nicol Bolas
288

La siguiente solución es lo suficientemente rápida y corta como para usarla en operaciones masivas y guardar bytes adicionales:

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

Aquí hay otra solución universal no regexp de una línea:

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

Ambos funcionan correctamente con nombres que no tienen extensión (por ejemplo, myfile ) o que comienzan con .punto (por ejemplo, .htaccess ):

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

Si le importa la velocidad, puede ejecutar el punto de referencia y verificar que las soluciones proporcionadas sean las más rápidas, mientras que la breve es tremendamente rápida:

Comparación de velocidad

Cómo funciona el corto:

  1. String.lastIndexOfEl método devuelve la última posición de la subcadena (es decir ".") en la cadena dada (es decir fname). Si no se encuentra la subcadena, el método devuelve -1.
  2. Las posiciones "inaceptables" de punto en el nombre de archivo son -1y 0, que se refieren respectivamente a nombres sin extensión (por ejemplo "name") y a nombres que comienzan con punto (por ejemplo ".htaccess").
  3. Zero-fill operador de desplazamiento a la derecha ( >>>) si se utiliza con cero afecta a números negativos transformar -1a 4294967295y -2a 4294967294, que es útil para el nombre de archivo restante sin cambios en los casos de borde (una especie de truco aquí).
  4. String.prototype.sliceextrae la parte del nombre de archivo de la posición que se calculó como se describe. Si el número de posición es mayor que la longitud del método de cadena devuelve "".

Si desea una solución más clara que funcione de la misma manera (además con soporte adicional de ruta completa), consulte la siguiente versión extendida. Esta solución será más lenta que las frases anteriores pero es mucho más fácil de entender.

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"

Las tres variantes deberían funcionar en cualquier navegador web en el lado del cliente y también se pueden usar en el código NodeJS del lado del servidor.

Visión
fuente
55
No funciona. "/home/user/.app/config" devuelve "app / config", lo cual es totalmente incorrecto.
mrbrdo
34
@mrbrdo Se supone que este método no funciona con la ruta completa solo con los nombres de archivo, según lo solicitado por la pregunta. Lea la pregunta cuidadosamente antes de votar hacia abajo.
VisioN
8
¿Por qué hacer todo lo posible para optimizar una línea de código tan trivial? Los operadores Tilde y Bitshift rara vez se ven en JavaScript que no puedo soportar tal respuesta. Si se necesitan 5 puntos para explicar cómo funciona 1 línea de código, es mejor reescribir el código para que sea realmente comprensible.
Jackson
66
La velocidad de esta línea no hará una diferencia perceptible en ninguna aplicación. Raramente se usa Bitwise que las linters populares como JSLint y JSHint advierten contra su uso. La obsesión por el rendimiento y la compacidad de esta lógica ha degradado la calidad del código; si el código requiere "investigación adicional", lo considero "malo".
Jackson
10
@Jackson Teniendo en cuenta que este es un sitio para ofrecer múltiples soluciones a un problema, tener una solución que optimice el rendimiento nunca es algo malo. Su declaración "no hará una diferencia perceptible en ninguna aplicación" se basa completamente en su alcance limitado de posibles aplicaciones en las que esto podría usarse. Más allá de eso, puede proporcionar a alguien que mira el problema una experiencia de aprendizaje en la que puede optimizar algunas otro código que necesitan para crear una aplicación informática intensiva que están escribiendo.
nrylee
33
function getFileExtension(filename)
{
  var ext = /^.+\.([^.]+)$/.exec(filename);
  return ext == null ? "" : ext[1];
}

Probado con

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

también

"a.b.c.d" (=> "d")
".a.b"    (=> "b")
"a..b"    (=> "b")
PhiLho
fuente
Para que funcione en IE: var pattern = "^. + \\. ([^.] +) $"; var ext = nuevo RegExp (patrón);
spc16670
20
function getExt(filename)
{
    var ext = filename.split('.').pop();
    if(ext == filename) return "";
    return ext;
}
Dima
fuente
8
volver (ext === nombre de archivo)? '': ext;
Michiel
13
var extension = fileName.substring(fileName.lastIndexOf('.')+1);
Pono
fuente
8
var parts = filename.split('.');
return parts[parts.length-1];
Randy Sugianto 'Yuku'
fuente
8
function file_get_ext(filename)
    {
    return typeof filename != "undefined" ? filename.substring(filename.lastIndexOf(".")+1, filename.length).toLowerCase() : false;
    }
Joe Scylla
fuente
8

Código

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

Prueba

Tenga en cuenta que, en ausencia de una consulta, el fragmento aún podría estar 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 advertencias.

Jack
fuente
7

Rápido y funciona correctamente con caminos

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

Algunos casos extremos

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

Las soluciones que usan división son lentas y las soluciones con lastIndexOf no manejan casos extremos.

mrbrdo
fuente
¿Qué casos extremos quieres decir? Consulte mi solución aquí: stackoverflow.com/a/12900504/1249581 . Funciona bien en todos los casos y mucho más rápido que cualquier expresión regular.
VisioN
Ya he enumerado los casos límite. Y su solución NO los maneja adecuadamente. Como ya he escrito, intente "/dir.with.dot/file". Su código devuelve "punto / archivo" que es ridículamente incorrecto.
mrbrdo
1
Nadie solicitó analizar el camino. La pregunta era sobre la extracción de extensiones de los nombres de archivo.
VisioN
3
Como ya te dije, eso nunca se dijo explícitamente, y una solución que maneja rutas es obviamente mucho más útil. Se supone que la respuesta a una pregunta sobre SO es útil para otras personas además de la persona que hizo la pregunta. Realmente no creo que una solución que maneje un superconjunto de entradas deba ser rechazada.
mrbrdo
3
El voto negativo fue para usar la variable global con .exec(). Su código será mejor como (filename.match(/[^\\/]\.([^\\/.]+)$/) || [null]).pop().
VisioN
6

Sólo quería compartir esto.

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

aunque esto tiene una desventaja de que los archivos sin extensión devolverán la última cadena. pero si lo haces, esto solucionará todo:

   function getExtention(fileName){
     var i = fileName.lastIndexOf('.');
     if(i === -1 ) return false;
     return fileName.slice(i)
   }
Hussein Nazzal
fuente
Por lo que recuerdo, el slicemétodo se refiere a matrices en lugar de cadenas. Para cuerdas substro substringfuncionará.
VisioN
@VisioN, pero supongo que deberías saber que existe String.prototype.slicey, Array.prototype.slicepor lo tanto, funciona de una manera un tanto método
Hussein Nazzal
1
Ah, sí. Tienes razón. Se olvidó por completo de este método. Culpa mía.
VisioN
5

Estoy seguro de que alguien puede minimizar y / u optimizar mi código en el futuro. Pero, en este momento , estoy 200% seguro de que mi código funciona en cada situación única (por ejemplo, solo con el nombre del archivo , con URL relativas , relativas a raíz y absolutas , con etiquetas de fragmentos # , con cadenas de consulta ? , y lo que sea de lo contrario, puede decidir lanzarle), sin problemas, y con precisión de punta.

Para pruebas, visite: https://projects.jamesandersonjr.com/web/js_projects/get_file_extension_test.php

Aquí está el JSFiddle: https://jsfiddle.net/JamesAndersonJr/ffcdd5z3/

No ser demasiado confiado, o soplar mi propia trompeta, pero no he visto ningún bloque de código para esta tarea (la búsqueda de la 'correcta' extensión de archivo, en medio de una batería de diferentes functionargumentos de entrada) que funciona tan bien como lo hace este.

Nota: Por diseño, si no existe una extensión de archivo para la cadena de entrada dada, simplemente devuelve una cadena en blanco "", no un error ni un mensaje de error.

Se necesitan dos argumentos:

  • Cadena: fileNameOrURL (se explica por sí mismo)

  • Boolean: showUnixDotFiles (si mostrar o no archivos que comienzan con un punto ".")

Nota (2): Si le gusta mi código, asegúrese de agregarlo a su biblioteca js y / o repositorios, porque trabajé duro para perfeccionarlo, y sería una pena desperdiciarlo. Así que sin más preámbulos, aquí está:

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

¡Disfrutar! ¡Eres muy bienvenido!:

James Anderson Jr.
fuente
1
Increíble. ¡Gracias!
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"));

山 茶树 和 葡萄 树
fuente
5

Si está tratando con URL web, puede usar:

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

Demostración: https://jsfiddle.net/squadjot/q5ard4fj/

Jakob Sternberg
fuente
Realmente me gusta tu solución. Hace mucho con tan poco. Lo voy a usar
Jules Manson
4

Prueba esto:

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

editar: Extrañamente (o tal vez no) el $1segundo argumento del método de reemplazo no parece funcionar ... Lo siento.

p4bl0
fuente
1
Funciona perfecto, pero se perdió que tendrá que eliminar todo el otro contenido de la cadena: return filename.replace (/^.*? \. ([A-zA-Z0-9] +) $ /, "$ 1");
Roenving
3

Me acabo de dar cuenta de que no es suficiente hacer un comentario sobre la respuesta de p4bl0, aunque la respuesta de Tom claramente resuelve el problema:

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

Para la mayoría de las aplicaciones, un script simple como

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

funcionaría bien (según lo provisto por Tom). Sin embargo, esto no es infalible. No funciona si se proporciona el siguiente nombre de archivo:

image.jpg?foo=bar

Puede ser un poco exagerado, pero sugeriría usar un analizador de URL como este para evitar fallas debido a nombres de archivo impredecibles.

Usando esa función en particular, podría obtener el nombre del archivo de esta manera:

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

Esto generará "image.jpg" sin los url vars. Entonces eres libre de agarrar la extensión del archivo.

Justin Bull
fuente
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
fuente
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;
}

//uso

extensión ('file.jpeg')

siempre devuelve la extensión minúscula para que pueda verificarla en el cambio de campo funciona para:

file.JpEg

archivo (sin extensión)

archivo. (sin extensión)

Jim Blackler
fuente
3

Si está buscando una extensión específica y conoce su longitud, puede usar substr :

var file1 = "50.xsl";

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

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

Jenny O'Reilly
fuente
1
La belleza viene con simplicidad. Esta es la respuesta más inteligente, más elegante y más eficiente de todas. Siempre usé String.substr (-3) o String.substr (-4) para tomar extensiones en sistemas basados ​​en Windows. ¿Por qué alguien querría usar expresiones regulares y bucles locos para eso?
asiby
13
@asiby Este tipo de soluciones es la razón principal por la que los cohetes espaciales se estrellan después del lanzamiento.
VisioN
3

Llego muchas lunas tarde a la fiesta, pero por simplicidad uso algo como esto

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
fuente
3

Hay una función de biblioteca estándar para esto en el pathmódulo:

import path from 'path';

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

Salida:

.TXT

Entonces, si solo quieres el formato:

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

Si no hay extensión, la función devolverá una cadena vacía:

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

Si está utilizando Node, entonces pathestá integrado. Si está apuntando al navegador, Webpack incluirá una pathimplementación para usted. Si está apuntando al navegador sin Webpack, entonces puede incluir path-browserify manualmente.

No hay razón para dividir cadenas o expresiones regulares.

sdgfsdh
fuente
¿Quién dijo algo sobre el nodo?
Shannon Hochkins el
Su argumento para no usar la división o las expresiones regulares es incluir el complemento o agrupar la aplicación con el nodo, es una respuesta exagerada para una tarea de
menor
@ShannonHochkins la mayoría de las veces tienes estas cosas configuradas de todos modos
sdgfsdh
@AndreiDraganescu No tenía la intención de que fuera condescendiente, así que lo he atenuado.
sdgfsdh
3

"one-liner" para obtener el nombre de archivo y la extensión usando reducey la desestructuración de la matriz :

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 mejor sangría:

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
fuente
Esto no funciona en IE 11
Gokul Maha
Puede usar babel / typecript / polyfills para las funciones faltantes de ES7 + de IE 11
boehm_s
2

Una solución de una línea que también tendrá en cuenta los parámetros de consulta y los caracteres en la 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
fuente
(1) Si un archivo no tiene extensión, esto aún devolverá el nombre del archivo. (2) Si hay un fragmento en la URL, pero no hay consulta (por ejemplo page.html#fragment), esto devolverá la extensión del archivo y el fragmento.
Jack
2

Esta solución simple

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

Pruebas

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

La respuesta de Wallacer es buena, pero se necesita una comprobación más.

Si el archivo no tiene extensión, usará el nombre del archivo como extensión, lo que no es bueno.

Prueba este:

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

No olvide que algunos archivos no pueden tener extensión, por lo tanto:

var parts = filename.split('.');
return (parts.length > 1) ? parts.pop() : '';
Tamás Pap
fuente
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
fuente
1
fetchFileExtention(fileName) {
    return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2);
}
GauRang Omar
fuente
2
Si bien este fragmento de código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no conocer los motivos de su sugerencia de código.
Brett DeWoody