Como posso obter extensões de arquivo com 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
fonte

Respostas:

796

Edição mais recente: Muitas coisas mudaram desde que esta pergunta foi publicada inicialmente - há muitas informações realmente boas na resposta revisada do wallacer, bem como a excelente repartição do VisioN


Edit: Só porque esta é a resposta aceita; a resposta do wallacer é realmente muito melhor:

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

Minha antiga resposta:

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

Deveria fazê-lo.

Edit: Em resposta ao comentário do PhiLho, use algo como:

return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined;
Tom
fonte
1
Não é caro executar o regex duas vezes?
Andrew Hedges
5
A resposta altamente cotada abaixo é muito melhor.
fletom
2
Infelizmente, ambas as soluções falham em nomes como arquivo e .htaccess .
VisioN 15/10/12
3
Todos os casos possíveis são processados ​​da seguinte forma: return filename.split ("."). Slice (1) .pop () || "";
JustAndrei
1
@JustAndrei Ainda não é tudo :) Por puro nome de arquivo (nome de base?), Não por um caminho, por razões práticas, acho que deveria ser. return filename.substring(0,1) === '.' ? '' : filename.split('.').slice(1).pop() || '';Isso também cuida dos .filetipos de arquivos (Unix oculto, acredito). Isto é, se você quiser mantê-lo como uma só linha, o que é um pouco confuso para o meu gosto.
Kooker
833
return filename.split('.').pop();

Mantenha simples :)

Editar:

Esta é outra solução não-regex que acredito ser mais eficiente:

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

Existem alguns casos de canto que são mais bem tratados pela resposta do VisioN abaixo, particularmente arquivos sem extensão ( .htaccessetc incluídos).

É muito eficiente e lida com casos de canto de uma maneira discutivelmente melhor retornando em ""vez da sequência completa quando não há ponto ou sequência antes do ponto. É uma solução muito bem trabalhada, embora difícil de ler. Coloque-o na sua biblioteca de ajudantes e use-a.

Edição antiga:

Uma implementação mais segura se você for encontrar arquivos sem extensão ou arquivos ocultos sem extensão (consulte o comentário do VisioN à resposta de Tom acima) seria algo nesse sentido

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.lengthfor um, é um arquivo visível sem extensão, ou seja. Arquivo

Se a[0] === ""e a.length === 2é um arquivo oculto sem extensão ou seja. .htaccess

Espero que isso ajude a esclarecer problemas com os casos um pouco mais complexos. Em termos de desempenho, acredito que esta solução é um pouco mais lenta que o regex na maioria dos navegadores. No entanto, para fins mais comuns, esse código deve ser perfeitamente utilizável.

wallacer
fonte
4
Não posso comentar sobre o desempenho, mas este certamente parece limpo! Estou usando isso. 1
pc1oad1etter
6
mas, nesse caso, o nome do arquivo se parece com filname.tes.test.jpg. Por favor, considere a saída. Espero que seja falso.
Fero
19
nesse caso, a saída é "jpg"
wallacer
1
Brilhante! Muito obrigado. É bom ver uma solução que não usa regex; Eu fiz isso com o PHP e ele usa apenas algumas funções. +1
Bojangles
3
@wallacer: O que acontece se filenamerealmente não tiver uma extensão? Isso simplesmente não retornaria o nome do arquivo base, o que seria meio ruim?
Nicol Bolas
288

A solução a seguir é rápida e curta o suficiente para usar em operações em massa e salvar bytes extras:

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

Aqui está outra solução universal não-regexp de uma linha:

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

Ambos funcionam corretamente com nomes sem extensão (por exemplo, meu arquivo ) ou começando com .ponto (por exemplo, .htaccess ):

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

Se você se preocupa com a velocidade, pode executar o benchmark e verificar se as soluções fornecidas são as mais rápidas, enquanto as menores são tremendamente rápidas:

Comparação de velocidade

Como o curto funciona:

  1. String.lastIndexOfO método retorna a última posição da substring (ie ".") na string especificada (ie fname). Se a substring não for encontrada, o método retornará -1.
  2. As posições "inaceitáveis" de ponto no nome do arquivo são -1e 0, que se referem respectivamente a nomes sem extensão (por exemplo "name") e a nomes que começam com ponto (por exemplo ".htaccess").
  3. O operador de deslocamento à direita de preenchimento zero ( >>>) se usado com zero afeta números negativos que se transformam -1em 4294967295e -2para 4294967294, o que é útil para manter o nome do arquivo inalterado nos casos de borda (tipo de truque aqui).
  4. String.prototype.sliceextrai a parte do nome do arquivo da posição que foi calculada conforme descrito. Se o número da posição for maior que o comprimento do método string, retornará "".

Se você deseja uma solução mais clara que funcione da mesma maneira (além de suporte extra de caminho completo), verifique a seguinte versão estendida. Essa solução será mais lenta que as one-liners anteriores, mas é muito mais 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"

Todas as três variantes devem funcionar em qualquer navegador da Web no lado do cliente e também podem ser usadas no código NodeJS do servidor.

Visão
fonte
5
Não funciona. "/home/user/.app/config" retorna "app / config", que está totalmente errado.
Mrbrdo 13/10
34
@mrbrdo Este método não deve funcionar com o caminho completo apenas com nomes de arquivos, conforme solicitado pela pergunta. Leia a pergunta com atenção antes de fazer a votação.
VisioN
8
Por que se esforçar para otimizar uma linha de código tão trivial? Os operadores til e shift shift são tão raramente vistos no JavaScript que não posso suportar essa resposta. Se forem necessários 5 pontos para explicar como uma linha de código funciona, é melhor reescrever o código para que ele seja realmente compreensível.
Jackson
6
A velocidade dessa linha não fará diferença perceptível em nenhuma aplicação. O Bitwise é tão raramente usado que linters populares como JSLint e JSHint alertam contra o uso deles. A obsessão pelo desempenho e compactação dessa lógica degradou a qualidade do código; se o código exigir "investigação extra", considero-o "ruim".
Jackson
10
@Jackson Considerando que este é um site que oferece várias soluções para um problema, ter uma solução que otimiza o desempenho nunca é uma coisa ruim. Sua afirmação "não fará diferença perceptível em nenhum aplicativo" baseia-se completamente no seu escopo restrito de aplicativos possíveis nos quais ele pode ser usado. Além disso, pode fornecer a alguém que está olhando para o problema uma experiência de aprendizado na qual pode otimizar alguns outro código que eles precisam criar para um aplicativo intensivo de computação que estão escrevendo.
nrylee
33
function getFileExtension(filename)
{
  var ext = /^.+\.([^.]+)$/.exec(filename);
  return ext == null ? "" : ext[1];
}

Testado com

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

Além disso

"a.b.c.d" (=> "d")
".a.b"    (=> "b")
"a..b"    (=> "b")
PhiLho
fonte
Para fazê-lo funcionar no IE: var pattern = "^. + \\. ([^.] +) $"; var ext = novo RegExp (padrão);
Spc16670 07/07
20
function getExt(filename)
{
    var ext = filename.split('.').pop();
    if(ext == filename) return "";
    return ext;
}
Dima
fonte
8
return (ext === nome do arquivo)? '': ext;
11134 Michiel
13
var extension = fileName.substring(fileName.lastIndexOf('.')+1);
Pono
fonte
8
var parts = filename.split('.');
return parts[parts.length-1];
Randy Sugianto 'Yuku'
fonte
8
function file_get_ext(filename)
    {
    return typeof filename != "undefined" ? filename.substring(filename.lastIndexOf(".")+1, filename.length).toLowerCase() : false;
    }
Joe Scylla
fonte
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
};

Teste

Observe que, na ausência de uma consulta, o fragmento ainda pode 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 avisos.

Jack
fonte
7

Rápido e funciona corretamente com caminhos

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

Alguns casos extremos

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

As soluções usando split são lentas e as soluções com lastIndexOf não lidam com casos extremos.

mrbrdo
fonte
Que casos extremos você quer dizer? Consulte a minha solução aqui: stackoverflow.com/a/12900504/1249581 . Funciona bem em todos os casos e muito mais rápido que em qualquer outro regex.
VisioN
Eu já listei os casos extremos. E sua solução NÃO os trata adequadamente. Como eu já escrevi, tente "/dir.with.dot/file". Seu código retorna "ponto / arquivo", o que é ridiculamente errado.
Mrbrdo 13/10
1
Ninguém pediu para analisar o caminho. A questão era sobre a extração de extensões de nomes de arquivos.
VisioN
3
Como eu já lhe disse, isso nunca foi explicitamente dito, e uma solução que lida com caminhos é obviamente muito mais útil. A resposta a uma pergunta sobre SO deve ser útil para outras pessoas além da pessoa que fez a pergunta. Realmente não acho que uma solução que lide com um superconjunto de entradas deva ser votada com menos votos.
Mrbrdo 18/10/2013
3
O voto negativo foi para usar a variável global com .exec(). Seu código será melhor como (filename.match(/[^\\/]\.([^\\/.]+)$/) || [null]).pop().
VisioN
6

Eu só queria compartilhar isso.

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

embora isso ocorra, os arquivos sem extensão retornarão a última string. mas se você fizer isso, isso corrigirá tudo:

   function getExtention(fileName){
     var i = fileName.lastIndexOf('.');
     if(i === -1 ) return false;
     return fileName.slice(i)
   }
Hussein Nazzal
fonte
Tanto quanto me lembro, o slicemétodo refere-se a matrizes e não a strings. Para cordas substrou substringvai funcionar.
VisioN
@VisioN mas eu acho que você deve saber que existe String.prototype.slicee também um Array.prototype.slicepara que ele meio que ambas as maneiras de trabalho meio de método
Hussein Nazzal
1
Ah sim. Você está certo. Esqueci completamente esse método. Foi mal.
VisioN
5

Tenho certeza de que alguém pode, e irá, minificar e / ou otimizar meu código no futuro. Mas, no momento , tenho 200% de certeza de que meu código funciona em todas as situações únicas (por exemplo, apenas com o nome do arquivo , com URLs relativas , relativas à raiz e absolutas , com tags de fragmento # , com strings de consulta ? e o que for caso contrário, você pode optar por jogá-lo), sem falhas e com precisão.

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

Aqui está o JSFiddle: https://jsfiddle.net/JamesAndersonJr/ffcdd5z3/

Para não ficar confiante demais, ou tocar meu próprio trompete, mas não vi nenhum bloco de código para esta tarefa (encontrar a extensão de arquivo 'correta' , em meio a uma bateria de functionargumentos de entrada diferentes ) que funciona tão bem quanto isso.

Nota: Por padrão, se uma extensão de arquivo não existir para a sequência de entrada especificada, ela simplesmente retorna uma sequência em branco "", não um erro nem uma mensagem de erro.

São necessários dois argumentos:

  • String: fileNameOrURL (auto-explicativo)

  • Booleano: showUnixDotFiles ( Mostrar ou não os arquivos que começam com um ponto ".")

Nota (2): Se você gosta do meu código, adicione-o às bibliotecas js e / ou repo, porque trabalhei duro para aperfeiçoá-lo e seria uma pena desperdiçar. Então, sem mais delongas, aqui 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;
    };

Aproveitar! Você é muito bem-vindo!:

James Anderson Jr.
fonte
1
Impressionante. Obrigado!
precisa saber é o seguinte
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"));

山 茶树 和 葡萄
fonte
5

Se você estiver lidando com URLs da Web, poderá 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

Demonstração: https://jsfiddle.net/squadjot/q5ard4fj/

Jakob Sternberg
fonte
Eu realmente gosto da sua solução. Faz muito com tão pouco. Eu vou usá-lo.
Jules Manson
4

Tente o seguinte:

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

edit: Estranhamente (ou talvez não seja) $1, o segundo argumento do método de substituição não parece funcionar ... Desculpe.

p4bl0
fonte
1
Funciona perfeitamente, mas você perdeu que precisará remover todo o conteúdo da string: return filename.replace (/^.*? \. ([A-zA-Z0-9] +) $ /, "$ 1");
roenving 10/10/08
3

Acabei de perceber que não basta comentar a resposta de p4bl0, embora a resposta de Tom resolva claramente o problema:

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

Para a maioria dos aplicativos, um script simples como

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

funcionaria muito bem (conforme fornecido por Tom). No entanto, isso não é à prova de idiotas. Não funciona se o seguinte nome de arquivo for fornecido:

image.jpg?foo=bar

Pode ser um pouco exagerado, mas eu sugiro o uso de um analisador de URL como este para evitar falhas devido a nomes de arquivos imprevisíveis.

Usando essa função específica, você pode obter o nome do arquivo assim:

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

Isso produzirá "image.jpg" sem os url vars. Então você está livre para pegar a extensão do arquivo.

Justin Bull
fonte
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
fonte
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

extensão ('file.jpeg')

sempre retorna a extensão inferior da extensão para que você possa verificá-la nas alterações de campo para:

file.JpEg

arquivo (sem extensão)

Arquivo. (sem extensão)

Jim Blackler
fonte
3

Se você está procurando uma extensão específica e conhece seu comprimento, pode usar substr :

var file1 = "50.xsl";

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

Referência do JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr

Jenny O'Reilly
fonte
1
A beleza vem com simplicidade. Essa é a resposta mais inteligente, elegante e eficiente de todas. Eu sempre usei String.substr (-3) ou String.substr (-4) para obter extensões em sistemas baseados no Windows. Por que alguém iria querer usar expressões regulares e loops loucos para isso?
asiby
13
@asiby Esse tipo de solução é a principal razão para os foguetes espaciais baterem após o lançamento.
VisioN
3

Estou muitas luas atrasado para a festa, mas por simplicidade eu uso algo assim

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

Há uma função de biblioteca padrão para isso no pathmódulo:

import path from 'path';

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

Resultado:

.TXT

Então, se você deseja apenas o formato:

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

Se não houver extensão, a função retornará uma string vazia:

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

Se você estiver usando o Node, então pathestá embutido. Se você estiver direcionando o navegador, o Webpack incluirá uma pathimplementação para você. Se você estiver direcionando o navegador sem o Webpack, poderá incluir o path-browserify manualmente.

Não há razão para fazer divisão de sequência ou regex.

sdgfsdh
fonte
Quem disse algo sobre o nó?
Shannon Hochkins
Seu argumento para a não utilização divisão ou expressões regulares é incluir plug-in ou pacote do aplicativo com nó, é uma sobre o topo resposta para uma tarefa servil
Shannon Hochkins
@ShannonHochkins na maioria das vezes você tem essas coisas configurar qualquer maneira
sdgfsdh
@AndreiDraganescu Eu não pretendia que fosse condescendente, então diminuí-lo.
sdgfsdh 13/01
3

"one-liner" para obter o nome do arquivo e a extensão usando reducee destruindo a 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});

com melhor indentação:

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
fonte
Isso não está funcionando no IE 11
Gokul Maha
Você pode usar o babel / typescript / polyfills para os recursos ES7 + ausentes do IE 11
boehm_s
2

Uma solução de uma linha que também considerará parâmetros de consulta e quaisquer caracteres no 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
fonte
(1) Se um arquivo não tiver extensão, ele ainda retornará o nome do arquivo. (2) Se houver um fragmento na URL, mas nenhuma consulta (por exemplo page.html#fragment), isso retornará a extensão do arquivo e o fragmento.
10242 Jack
2

Esta solução simples

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

Testes

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

A resposta do Wallacer é boa, mas é necessária mais uma verificação.

Se o arquivo não tiver extensão, ele usará o nome do arquivo como extensão, o que não é bom.

Tente este:

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

Não esqueça que alguns arquivos não podem ter extensão, portanto:

var parts = filename.split('.');
return (parts.length > 1) ? parts.pop() : '';
Tamás Pap
fonte
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
fonte
1
fetchFileExtention(fileName) {
    return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2);
}
GauRang Omar
fonte
2
Embora esse trecho de código possa resolver a questão, incluir uma explicação realmente ajuda a melhorar a qualidade da sua postagem. Lembre-se de que você está respondendo à pergunta dos leitores no futuro e essas pessoas podem não saber os motivos da sua sugestão de código.
Brett DeWoody 27/03