2008-10-10 12 views

Respuesta

505

Las siguientes diferencias: Muchas cosas han cambiado desde que esta pregunta fue publicada inicialmente - hay una gran cantidad de información muy buena en wallacer's revised answer, así como VisioN's excellent breakdown


Editar: El hecho de que este es el respuesta aceptada; wallacer's answer es de hecho mucho mejor:

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

Mi vieja respuesta:

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

debe hacerlo.

Editar: En respuesta al comentario de PhiLho, usar algo como:

return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined; 
+8

Devuelve el nombre del archivo si no tiene extensión ... – PhiLho

+1

¿No es costoso ejecutar la expresión regular dos veces? –

+0

¿es mejor utilizar expresiones regulares que el último índice? Gracias. – melaos

2
return filename.replace(/\.([a-zA-Z0-9]+)$/, "$1"); 

edición: Extrañamente (o tal vez no lo es) el $1 en el segundo argumento del método replace no parece funcionar ... Lo siento.

+1

Funciona perfecto, pero se ausentó que tendrá que elimine todo el resto del contenido de la cadena: return filename.replace (/^.*? \. ([a-zA-Z0-9] +) $ /, "$ 1"); – roenving

7
var parts = filename.split('.'); 
return parts[parts.length-1]; 
19
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") 
+1

No es la respuesta más simple, pero la correcta. –

+0

Para que funcione en IE: var pattern = "^. + \\. ([^.] +) $"; var ext = new RegExp (patrón); – coolfeature

7
function file_get_ext(filename) 
    { 
    return typeof filename != "undefined" ? filename.substring(filename.lastIndexOf(".")+1, filename.length).toLowerCase() : false; 
    } 
+0

este código funciona bien – Fero

2

me he dado cuenta de que no es suficiente para poner un comentario en la respuesta de p4bl0, aunque la respuesta de Tom resuelve claramente el problema:

return filename.replace(/^.*?\.([a-zA-Z0-9]+)$/, "$1"); 
2
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 ('archivo // .jpeg ')

siempre devuelve la extensión inferior cas para que pueda verificarlo en el campo de cambio funciona para:

file.JpEg

archivo (sin extensión)

archivo.(Noextension)

2
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"); 
    } 
} 
+0

.png no es una imagen? –

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

Debe ser sencillo :)

Editar:

Ésta es otra solución no expresiones regulares que creo que es más eficiente:

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

Hay algunos casos de esquina que son mejor manejados por VisioN's answer a continuación, particularmente archivos sin extensión (.htaccess etc. incluidos).

Es muy eficiente, y maneja casos de esquina de una manera posiblemente mejor al devolver "" en lugar de la cadena completa cuando no hay punto o ninguna cuerda antes del punto. Es una solución muy bien diseñada, aunque difícil de leer. Mételo en tu lib de ayudantes y solo úsalo.

Editar antigua:

Una aplicación más seguro si se va a ejecutar en archivos sin extensión, o archivos ocultos sin extensión (véase el comentario de la visión a la respuesta de Tom arriba) sería algo a lo largo de estas líneas

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 decir extensión. archivo

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

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

+4

No puedo comentar sobre el rendimiento, ¡pero este ciertamente se ve limpio! Lo estoy usando. +1 – pc1oad1etter

+5

pero en este caso el nombre del archivo se ve como filname.tes.test.jpg. Tenga en cuenta la salida. Espero que sea falso. – Fero

+19

en ese caso, la salida es "jpg" – wallacer

2

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

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

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

image.jpg?foo=bar 

Puede ser un poco exagerado pero sugeriría el uso de un analizador de enlace como this one para evitar fallos debidos a los nombres de archivo impredecibles.

El uso de esa función en particular, se puede obtener el nombre del archivo como esto:

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

Esta es la salida "imagen.jpg" sin la url vars. Entonces eres libre de tomar la extensión del archivo.

3

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; 
} 
17
function getExt(filename) 
{ 
    var ext = filename.split('.').pop(); 
    if(ext == filename) return ""; 
    return ext; 
} 
+4

return (ext === filename)? '': ext; – Michiel

+2

¿no fallaría en jpg.jpg o txt.txt? – Miro

11
var extension = fileName.substring(fileName.lastIndexOf('.')+1); 
208

La siguiente solución es rápida y cortos suficiente para su uso en las operaciones a granel y guardar bytes adicionales:

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

Aquí es otro sol universal no regexp de una sola línea ution:

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

Ambos funcionan correctamente con nombres que no tienen extensión (p. mi_archivo) o empezar con . punto (por ejemplo .htaccess):

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

Si se preocupan por la velocidad que puede correr el benchmark y comprobar que las soluciones aportadas son los más rápidos, mientras que el corto es tremendamente rápido:

Speed comparison

¿Cómo funciona la corta:

  1. String.lastIndexOf 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 -1 y 0, que se refieren respectivamente a los nombres sin extensión (por ejemplo "name") y a nombres que comienzan con el punto (por ejemplo ".htaccess").
  3. Zero-fill right shift operator (>>>) si se utiliza con cero afecta números negativos transformación -1 a 4294967295 y -2-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.slice extrae la parte del nombre de archivo de la posición que se calculó como se describe. Si el número de posición es más que la longitud del método de cadena, devuelve "".

Si desea una solución más clara que funcionará de la misma manera (además con el apoyo adicional de la ruta completa), compruebe lo siguiente versión extendida. Esta solución será más lenta que las líneas 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" 

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

+7

Me pregunto por qué las personas no han votado a favor esta solución, funciona perfectamente. – Ajit

+0

porque wtf es eso? (¡lo estoy usando!) – sent1nel

+0

@Zipp Para hacerlo más comprensible, he agregado la descripción del enfoque y la comparación de velocidad para ilustrar qué tan rápido es la solución. – VisioN

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 de archivo como extensión que no es buena.

Prueba con esto:

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

No se olvide que algunos archivos pueden tener ninguna extensión, por lo que:

var parts = filename.split('.'); 
return (parts.length > 1) ? parts.pop() : ''; 
4

rápida y funciona correctamente con caminos

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

Algunos borde casos

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

Las soluciones que utilizan split son lentas y las soluciones con lastIndexOf no manejan casos de borde.

+0

¿Qué casos extremos quiere decir? Consulte mi solución aquí: http://stackoverflow.com/a/12900504/1249581. Funciona bien en todos los casos y mucho más rápido que cualquier regex. – VisioN

+0

Ya he enumerado los casos extremos. Y su solución NO los maneja adecuadamente. Como ya he escrito, pruebe "/dir.with.dot/file". Tu código devuelve "punto/archivo" que es ridículamente incorrecto. – mrbrdo

+0

Nadie pidió analizar la ruta. La pregunta era sobre extraer extensiones de nombres de archivos. – VisioN

3

solo quería compartir esto.

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

aunque esto tiene la desventaja de que los archivos sin extensión devolverán la última cadena. pero si lo hace Esto solucionará cualquier cosa:

function getExtention(fileName){ 
    var i = fileName.lastIndexOf('.'); 
    if(i === -1) return false; 
    return fileName.slice(i) 
    } 
+0

Por lo que recuerdo, el método 'slice 'se refiere a las matrices en lugar de a las cadenas. Para las cadenas 'substr' o' substring' funcionará. – VisioN

+0

@VisioN pero supongo que usted debe saber que existe 'String.prototype.slice' y también un' Array.prototype.slice' Es un poco así que ambas formas de trabajo un poco de método –

+1

Ah, sí. Tienes razón. Olvidé por completo este método. Mi error. – VisioN

0
var filetypeArray = (file.type).split("/"); 
var filetype = filetypeArray[1]; 

Esta es una mejor aproximación de la OMI.

2

Si usted está buscando una extensión específica y saber su longitud, puede utilizar substr:

referencia
var file1 = "50.xsl"; 

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

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

+1

La belleza viene con simplicidad. Esta es la respuesta más inteligente, más elegante y más eficiente de todas. Siempre utilicé String.substr (-3) o String.substr (-4) para obtener extensiones en sistemas basados ​​en Windows. ¿Por qué alguien querría usar expresiones regulares y loops locos para eso? – asiby

+11

@asiby Este tipo de soluciones es la razón principal por la que los cohetes espaciales colapsan después del lanzamiento. – VisioN

2

estoy 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>

0

En Node.js, esto se puede lograr mediante el siguiente código:

var file1 ="50.xsl"; 
var path = require('path'); 
console.log(path.parse(file1).name); 
2

Una solución de una línea que también dar cuenta de Parámetros de consulta y otros 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 
+0

** (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 consulta (por ejemplo, 'page.html # fragment'), esto devolverá la extensión del archivo y el fragmento. – Jack

0
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 
4

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

en cuenta que en ausencia de una consulta, el fragmento todavía 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 cuidado.

1

Esta sencilla solución

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

0

estoy seguro de que alguien pueda, y lo hará, Minify y/u optimizar mi código en el futuro. Pero, a partir de ahora, estoy 200% seguro de que mi código funciona en cada situación única (por ejemplo, con sólo el nombre archivo sólo, con relativa, relativa a la raíz y absoluta URL, con fragmento# etiquetas, con consulta? cadenas, y cualquier otra cosa que decida tirar), sin problemas, y con precisión de punto de pin.

Como prueba, visite: https://projects.jamesandersonjr.com/web/js_projects/get_file_extension_test.php

Aquí está la jsFiddle: https://jsfiddle.net/JamesAndersonJr/ffcdd5z3/

No ser demasiado confiado, o soplar mi propia trompeta, pero no he visto cualquier bloque de código para esta tarea (encontrar la extensión de archivo 'correcta', en medio de una batería de diferentes argumentos de entrada function) que funciona tan bien como esto.

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

Se necesitan dos argumentos:

  • cadena: fileNameOrURL(auto-explicativo)

  • booleanas: showUnixDotFiles (sea o no a mostrar los archivos que comienzan con un punto)

Nota (2) "": Si te gusta mi código, asegúrese de añadirlo a su js biblioteca, y/o cesión temporal de, porque trabajé duro en perfeccionarlo, y sería una pena desperdiciarlo.Entonces, 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; 
    }; 

¡Disfrútalo! Eres muy Bienvenido !:

0

Si se trata de direcciones URL, puede utilizar:

function getExt(filename){ 
    return filename.split('.').pop().split("?")[0].split("#")[0]; 
} 

getExt("logic.v2.min.js") // js 
getExt("http://example.net/site/page.php?id=16548") // php 
getExt("http://example.net/site/page.html#welcome") // html 

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

+0

Me gusta mucho su solución. Hace tanto con tan poco. Voy a usarlo. –

Cuestiones relacionadas