How to extract the extension of a file in Javascript?

19

There are some cases where I need to capture the extension of a file (that is, a string with file address) to be able to validate the extension via Javascript.

For example, location :

var path = window.location.pathname;
// /foo/bar.html

In case I want to get the html .

There is also the case of treating the extension of a link element, for example:

var path = document.querySelector('link').src;
// http://algum.site/css/estilo.css

In case you would have to return css .

What better way to get this extension?

Regarding URL cases:

'foo/bar.ext'     // 'ext'
'foo.bar/zaz.ext' // 'ext'
'foo.bar/sem_ext' // ''
'.sem_ext'        // ''
'foo/.sem_ext'    // ''
    
asked by anonymous 28.02.2014 / 22:20

4 answers

18

To get the extension of a file in a practical way:

var ext = path.split('.').pop();

In this case, split divided the path into an array and pop will remove and return the last element of this array, just the extension I'm looking for.

A more accurate version would be:

// Pegar somente a ultima parte, afinal podem ter pastas com . no caminho
var ext = path.split('/').pop();
// se não houver extensão, retorna vazio, se houver retorna a extensão
// sendo que .htaccess é um arquivo escondido e não uma extensão
ext = ext.indexOf('.') < 1 ? '' : ext.split('.').pop();

But you can also do this using lastIndexOf with some mathematical operations to get better performance , example :

function ext(path) {
    var idx = (~-path.lastIndexOf(".") >>> 0) + 2;
    return path.substr((path.lastIndexOf("/") - idx > -3 ? -1 >>> 0 : idx));
}

In this second solution, I used the concept presented by bfavaretto but in a little more performative way.

Explaining the second solution

First we find the position of . , but since we're going to use substr then it's important to know that in substr if you put a value greater than string , it goes return empty.

Then we use the - operator to turn the value into negative.

Then the ~ operator that will invert the binary value (ex: 0010 turns 1101 ) this operation is done exactly to skip if the file starts with . or if it does not have . give it a negative value.

With the >>> operator, we are moving the positioning in bits into unsigned (positive) value, which in the case of being negative to 0 will give the largest possible integer minus the value being passed in the result of the previous calculation and if it is positive nothing will happen to be changed.

Then add 2 to compensate for ~- operations at the end.

In the next line we have a conditional so that the position of the last / is less than the last point position or if it is a point next, so the less than -3, so apply the same logic to the substr if the value is invalid giving a very large number for it.

28.02.2014 / 22:20
9

The logic for extracting the extension with these requirements is to isolate the last part of the path, and check:

  • If it is blank, it starts with a dot or does not contain a dot: it returns '' .
  • Otherwise: return whatever comes after the period.

You can break the path into arrays , as demonstrated by Gabriel Gartz. It's the simplest way .

An option that does not involve arrays, only with string manipulation, is usually more performace . It's about using lastIndexOf to break the path:

function ext(path) {
    var final = path.substr(path.lastIndexOf('/')+1);
    var separador = final.lastIndexOf('.');
    return separador <= 0 ? '' : final.substr(separador + 1);
}
    
28.02.2014 / 22:34
6

I like the regular expression approach:

function getExtension(path) {
  var r = /\.([^./]+)$/.exec(path);
  return r && r[1] || '';
}

The regular expression will look for a "dot", followed by any other characters, except for another dot or a slash. The $ at the end of the expression requires it to be the end of the string.

If this pattern is found in the string, the function returns the 1st catch, ie the letters following the last point. Otherwise, it will return empty string.

Explanation regexper >

    
01.03.2014 / 22:37
3

As you want to take into account files without extension, as in the case of .htaccess, it requires a bit more code:

var filename = window.location.pathname.split('/')[window.location.pathname.split('/').length-1].split('.');
var ext = filename[0].length > 0 ? filename[1] : '';
alert(ext)
    
01.03.2014 / 03:17