¿Cómo puedo obtener extensiones de archivos con JavaScript?
Ver código:
var file1 = "50.xsl";
var file2 = "30.doc";
getFileExtension(file1); //returns xsl
getFileExtension(file2); //returns doc
function getFileExtension(filename) {
/*TODO*/
}
Edición más reciente: muchas cosas han cambiado desde que se publicó inicialmente esta pregunta; hay mucha 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 antigua respuesta:
return /[^.]+$/.exec(filename);
Deberías hacerlo.
Editar: en respuesta al comentario de PhiLho, use algo como:
return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined;
return filename.split('.').pop();
Editar:
Esta es otra solución sin expresiones regulares que creo que es más eficiente:
return filename.substring(filename.lastIndexOf('.')+1, filename.length) || filename;
Hay algunos casos extremos que se manejan mejor con la respuesta de VisioN a continuación, particularmente archivos sin extensión ( .htaccess
etc. 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 ningún punto o ninguna cadena antes del punto. Es una solución muy bien diseñada, aunque difícil de leer. Pégalo en la biblioteca de tus ayudantes y úsalo.
Edición antigua:
Una implementación más segura si va a encontrar archivos sin extensión o archivos ocultos sin extensión (consulte el comentario de VisioN a la respuesta de Tom arriba) sería algo parecido a esto
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
es uno, es un archivo visible sin extensión, es decir. archivo
Si a[0] === ""
y a.length === 2
es un archivo oculto sin extensión, es decir. .htaccess
Esto deberí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 las expresiones regulares en la mayoría de los navegadores. Sin embargo, para los propósitos más comunes, este código debería ser perfectamente utilizable.
La siguiente solución es lo suficientemente rápida y breve para usarla en operaciones masivas y ahorrar bytes adicionales:
return fname.slice((fname.lastIndexOf(".") - 1 >>> 0) + 2);
Aquí hay otra solución universal de una línea sin expresión regular:
return fname.slice((Math.max(0, fname.lastIndexOf(".")) || Infinity) + 1);
Ambos funcionan correctamente con nombres que no tienen extensión (por ejemplo, miarchivo ) o que comienzan con .
un 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 comprobar que las soluciones proporcionadas son las más rápidas, mientras que la corta es tremendamente rápida:
Cómo funciona el corto:
String.lastIndexOf
El 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
.- Las posiciones "inaceptables" del punto en el nombre del archivo son
-1
y0
, que se refieren respectivamente a nombres sin extensión (p. ej."name"
) y a nombres que comienzan con un punto (p. ej.".htaccess"
). - El operador de desplazamiento a la derecha de relleno cero (
>>>
) si se usa con cero afecta los números negativos que se transforman-1
hacia4294967295
y-2
hacia4294967294
, lo cual es útil para mantener el nombre del archivo sin cambios en los casos extremos (una especie de truco aquí). String.prototype.slice
extrae la parte del nombre del archivo de la posición que se calculó como se describe. Si el número de posición es mayor que la longitud de la cadena, el método devuelve""
.
Si desea una solución más clara que funcione de la misma manera (además de soporte adicional para la ruta completa), consulte la siguiente versión extendida. Esta solución será más lenta que las 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 del lado del cliente y también pueden usarse en el código NodeJS del lado del servidor.
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")