¿Cómo obtener el nombre del archivo de una ruta completa usando JavaScript?

310

¿Hay alguna manera de que pueda obtener el último valor (basado en el símbolo '\') de una ruta completa?

Ejemplo:

C:\Documents and Settings\img\recycled log.jpg

Con este caso, solo quiero obtener recycled log.jpgde la ruta completa en JavaScript.

Jin Yong
fuente

Respuestas:

698
var filename = fullPath.replace(/^.*[\\\/]/, '')

Esto manejará las rutas \ OR / in

nickf
fuente
44
No funciona en MAC OSX, usando Chrome, se escapa del personaje después de \
Pankaj Phartiyal
77
Según este sitio, el uso replacees mucho más lento que substr, lo que se puede usar junto con lastIndexOf('/')+1: jsperf.com/replace-vs-substring
Nate
1
@nickf Nick, no estoy seguro de dónde me estoy equivocando, pero el código no funciona para mí cuando la ruta del archivo tiene una sola barra inclinada. Fiddle, aunque para `\\` , funciona bien.
Shubh
1
Acabo de ejecutar esto en mi consola, y funcionó perfecto para barras diagonales: "/var/drop/foo/boo/moo.js".replace(/^.*[\\\/]/, '')devolucionesmoo.js
vikkee
1
@ZloySmiertniy Hay un par de buenos explicadores de expresiones regulares en línea. rick.measham.id.au/paste/explain.pl?regex=%2F%5E . *% 5B% 5C% 5C% 5C% 2F% 5D% 2F y regexper.com/#%2F%5E . *% 5B % 5C% 5C% 5C% 2F% 5D% 2F debería ayudar. (Los enlaces están rotos aquí, pero copie y pegue en una pestaña y funcionará)
nickf
115

Solo por el bien del rendimiento, probé todas las respuestas dadas aquí:

var substringTest = function (str) {
    return str.substring(str.lastIndexOf('/')+1);
}

var replaceTest = function (str) {
    return str.replace(/^.*(\\|\/|\:)/, '');
}

var execTest = function (str) {
    return /([^\\]+)$/.exec(str)[1];
}

var splitTest = function (str) {
    return str.split('\\').pop().split('/').pop();
}

substringTest took   0.09508600000000023ms
replaceTest   took   0.049203000000000004ms
execTest      took   0.04859899999999939ms
splitTest     took   0.02505500000000005ms

Y el ganador es la respuesta al estilo Split y Pop , ¡Gracias a bobince !

Danpe
fuente
44
Según la meta discusión, agregue la cita apropiada a otras respuestas. También sería útil explicar mejor cómo analizó el tiempo de ejecución.
jpmc26
Siéntase libre de comparar esta versión también. Debería admitir rutas de archivos Mac y Windows. path.split(/.*[\/|\\]/)[1];
tfmontague
2
La prueba es incorrecta. substringTest busca solo la barra diagonal, execTest - solo la barra diagonal inversa mientras que dos restantes manejan ambas barras diagonales. Y los resultados reales ya no son relevantes (más). Mira esto: jsperf.com/name-from-path
Duelo
@ Lamento que ese enlace ya no sea válido.
paqogomez
88

En Node.js, puede usar el módulo de análisis de Path ...

var path = require('path');
var file = '/home/user/dir/file.txt';

var filename = path.parse(file).base;
//=> 'file.txt'
RobLoach
fuente
14
Si usa Node.js puede usar la basenamefunción:path.basename(file)
electrovir
66

¿De qué plataforma proviene el camino? Las rutas de Windows son diferentes de las rutas POSIX son diferentes de las rutas de Mac OS 9 son diferentes de las rutas del sistema operativo RISC son diferentes ...

Si se trata de una aplicación web donde el nombre de archivo puede provenir de diferentes plataformas, no hay una solución única. Sin embargo, una puñalada razonable es usar '\' (Windows) y '/' (Linux / Unix / Mac y también una alternativa en Windows) como separadores de ruta. Aquí hay una versión que no es RegExp para mayor diversión:

var leafname= pathname.split('\\').pop().split('/').pop();
bobince
fuente
Es posible que desee agregar que MacOS clásico (<= 9) usaba separadores de dos puntos (:), pero no conozco ningún navegador que todavía esté en uso y que no haya traducido rutas de MacOS a rutas POSIX en forma de archivo : ///path/to/file.ext
párpado
44
Puede usar pop () en lugar de reverse () [0]. También modifica la matriz original, pero está bien en su caso.
Chetan Sastry el
Me pregunto cómo podemos crear una contraparte para obtener solo el camino.
Todd Horst
Algo así como var path = '\\Dir2\\Sub1\\SubSub1'; //path = '/Dir2/Sub1/SubSub1'; path = path.split('\\').length > 1 ? path.split('\\').slice(0, -1).join('\\') : path; path = path.split('/').length > 1 ? path.split('/').slice(0, -1).join('/') : path; console.log(path);
Todd Horst
Nombrar " nombre de hoja " se deriva del directorio / nombre de estructura de archivo "Árbol", lo primero del árbol es raíz , las últimas son las hojas => el nombre del archivo es lo último en la ruta del árbol => hoja :-)
jave. web
29

Ates, su solución no protege contra una cadena vacía como entrada. En ese caso, falla con TypeError: /([^(\\|\/|\:)]+)$/.exec(fullPath) has no properties.

Bobince, aquí hay una versión de nickf que maneja delimitadores de ruta DOS, POSIX y HFS (y cadenas vacías):

return fullPath.replace(/^.*(\\|\/|\:)/, '');
usuario129661
fuente
44
si estamos escribiendo este código JS en PHP, necesitamos agregar un \ adicional para cada \
Lenin Raj Rajasekaran
17

La siguiente línea de código JavaScript le dará el nombre del archivo.

var z = location.pathname.substring(location.pathname.lastIndexOf('/')+1);
alert(z);
Epperlyg
fuente
10

No es más conciso que la respuesta de nickf , pero esta directamente "extrae" la respuesta en lugar de reemplazar las partes no deseadas con una cadena vacía:

var filename = /([^\\]+)$/.exec(fullPath)[1];
Ates Goral
fuente
8

Una pregunta que pregunta "obtener nombre de archivo sin extensión" se refiere aquí, pero no hay solución para eso. Aquí está la solución modificada de la solución de Bobbie.

var name_without_ext = (file_name.split('\\').pop().split('/').pop().split('.'))[0];
Raymond Sin
fuente
6

Otro

var filename = fullPath.split(/[\\\/]/).pop();

Aquí la división tiene una expresión regular con una clase de caracteres.
Los dos caracteres deben escaparse con '\'

O use la matriz para dividir

var filename = fullPath.split(['/','\\']).pop();

Sería la forma de empujar dinámicamente más separadores en una matriz, si es necesario.
Si fullPathse establece explícitamente por una cadena en su código, ¡debe escapar de la barra invertida !
Me gusta"C:\\Documents and Settings\\img\\recycled log.jpg"


fuente
3

Yo suelo:

var lastPart = path.replace(/\\$/,'').split('\\').pop();

Reemplaza el último, \por lo que también funciona con carpetas.

pomber
fuente
2
<script type="text/javascript">
    function test()
    {
        var path = "C:/es/h221.txt";
        var pos =path.lastIndexOf( path.charAt( path.indexOf(":")+1) );
        alert("pos=" + pos );
        var filename = path.substring( pos+1);
        alert( filename );
    }
</script>
<form name="InputForm"
      action="page2.asp"
      method="post">
    <P><input type="button" name="b1" value="test file button"
    onClick="test()">
</form>
Peter Mortensen
fuente
1

La respuesta completa es:

<html>
    <head>
        <title>Testing File Upload Inputs</title>
        <script type="text/javascript">

        function replaceAll(txt, replace, with_this) {
            return txt.replace(new RegExp(replace, 'g'),with_this);
        }

        function showSrc() {
            document.getElementById("myframe").href = document.getElementById("myfile").value;
            var theexa = document.getElementById("myframe").href.replace("file:///","");
            var path = document.getElementById("myframe").href.replace("file:///","");
            var correctPath = replaceAll(path,"%20"," ");
            alert(correctPath);
        }
        </script>
    </head>
    <body>
        <form method="get" action="#"  >
            <input type="file"
                   id="myfile"
                   onChange="javascript:showSrc();"
                   size="30">
            <br>
            <a href="#" id="myframe"></a>
        </form>
    </body>
</html>
Sandeep Kumar
fuente
1

Pequeña función para incluir en su proyecto para determinar el nombre de archivo de una ruta completa para Windows, así como las rutas absolutas GNU / Linux y UNIX.

/**
 * @param {String} path Absolute path
 * @return {String} File name
 * @todo argument type checking during runtime
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf
 * @example basename('/home/johndoe/github/my-package/webpack.config.js') // "webpack.config.js"
 * @example basename('C:\\Users\\johndoe\\github\\my-package\\webpack.config.js') // "webpack.config.js"
 */
function basename(path) {
  let separator = '/'

  const windowsSeparator = '\\'

  if (path.includes(windowsSeparator)) {
    separator = windowsSeparator
  }

  return path.slice(path.lastIndexOf(separator) + 1)
}
Amin NAIRI
fuente
0
<html>
    <head>
        <title>Testing File Upload Inputs</title>
        <script type="text/javascript">
            <!--
            function showSrc() {
                document.getElementById("myframe").href = document.getElementById("myfile").value;
                var theexa = document.getElementById("myframe").href.replace("file:///","");
                alert(document.getElementById("myframe").href.replace("file:///",""));
            }
            // -->
        </script>
    </head>
    <body>
        <form method="get" action="#"  >
            <input type="file" 
                   id="myfile" 
                   onChange="javascript:showSrc();" 
                   size="30">
            <br>
            <a href="#" id="myframe"></a>
        </form>
    </body>
</html>
Semere Hailu
fuente
1
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 saber los motivos de su sugerencia de código.
Ferrybig
0

Script exitoso para su pregunta, Prueba completa

<script src="~/Scripts/jquery-1.10.2.min.js"></script>

<p  title="text" id="FileNameShow" ></p>
<input type="file"
   id="myfile"
   onchange="javascript:showSrc();"
   size="30">


<script type="text/javascript">

function replaceAll(txt, replace, with_this) {
    return txt.replace(new RegExp(replace, 'g'), with_this);
}

function showSrc() {
    document.getElementById("myframe").href = document.getElementById("myfile").value;
    var theexa = document.getElementById("myframe").href.replace("file:///", "");
    var path = document.getElementById("myframe").href.replace("file:///", "");
    var correctPath = replaceAll(path, "%20", " ");
   alert(correctPath);
    var filename = correctPath.replace(/^.*[\\\/]/, '')
    $("#FileNameShow").text(filename)
}

Amin Saadati
fuente
0

Esta solución es mucho más simple y genérica, tanto para 'nombre de archivo' como para 'ruta'.

const str = 'C:\\Documents and Settings\\img\\recycled log.jpg';

// regex to split path to two groups '(.*[\\\/])' for path and '(.*)' for file name
const regexPath = /^(.*[\\\/])(.*)$/;

// execute the match on the string str
const match = regexPath.exec(str);
if (match !== null) {
    // we ignore the match[0] because it's the match for the hole path string
    const filePath = match[1];
    const fileName = match[2];
}
Hicham
fuente
La calidad de una respuesta se puede mejorar agregando alguna explicación a su código. Algunas personas que buscan esta respuesta pueden ser nuevas en la codificación o en las expresiones regulares, y un pequeño texto para dar contexto ayudará mucho a la comprensión.
jmarkmurphy
espero que así sea mejor :)
Hicham
-3
function getFileName(path, isExtension){

  var fullFileName, fileNameWithoutExtension;

  // replace \ to /
  while( path.indexOf("\\") !== -1 ){
    path = path.replace("\\", "/");
  }

  fullFileName = path.split("/").pop();
  return (isExtension) ? fullFileName : fullFileName.slice( 0, fullFileName.lastIndexOf(".") );
}
Tomás
fuente
-3

var file_name = file_path.substring(file_path.lastIndexOf('/'));

shriniket
fuente