Como obter o nome do arquivo de um caminho completo usando JavaScript?

310

Existe uma maneira de obter o último valor (com base no símbolo '\') de um caminho completo?

Exemplo:

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

Nesse caso, eu só quero ir recycled log.jpgdo caminho completo em JavaScript.

Jin Yong
fonte

Respostas:

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

Isso manipulará os caminhos \ OR / in

nickf
fonte
4
Não funciona em MAC OSX, usando cromo, ele escapa de caracteres depois de \
Pankaj Phartiyal
7
De acordo com este site, o uso replaceé muito mais lento que o substrque pode ser usado em conjunto com lastIndexOf('/')+1: jsperf.com/replace-vs-substring
Nate
1
@ Nickf Nick, não sei onde estou indo errado, mas o código não funciona para mim quando o caminho do arquivo está tendo barra única. Fiddle, embora para `\\` funcione bem.
21814 Shubh
1
Acabei de executar isso no meu console, e ele funcionou perfeito para barras: "/var/drop/foo/boo/moo.js".replace(/^.*[\\\/]/, '')retornosmoo.js
vikkee
1
@ZloySmiertniy Existem alguns bons explicadores de regex online. rick.measham.id.au/paste/explain.pl?regex=%2F%5E . *% 5B% 5C% 5C% 5C% 5C% 2F% 5D% 2F e regexper.com/#%2F%5E . *% 5B % 5C% 5C% 5C% 2F% 5D% 2F deve ajudar. (As ligações são quebradas aqui, mas copiar-colar em uma guia e ele vai trabalhar)
nickf
115

Apenas por uma questão de desempenho, testei todas as respostas dadas aqui:

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

E o vencedor é a resposta ao estilo Split e Pop , Obrigado a Bobince !

Danpe
fonte
4
De acordo com a meta discussão, adicione citações apropriadas a outras respostas. Também seria útil explicar melhor como você analisou o tempo de execução.
Jpmc26
Sinta-se à vontade para comparar essa versão também. Deve oferecer suporte aos caminhos de arquivo do Mac e do Windows. path.split(/.*[\/|\\]/)[1];
precisa saber é o seguinte
2
O teste está incorreto. substringTest procura apenas barra invertida, execTest - apenas barra invertida, enquanto os dois restantes lidam com as duas barras. E os resultados reais não são relevantes (mais). Verifique isso: jsperf.com/name-from-path
Grief
@Luto esse link não é mais válido.
paqogomez
88

No Node.js, você pode usar o módulo de análise do Path ...

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

var filename = path.parse(file).base;
//=> 'file.txt'
RobLoach
fonte
14
Se estiver usando o Node.js, você pode simplesmente usar a basenamefunção:path.basename(file)
electrovir
66

De que plataforma vem o caminho? Os caminhos do Windows são diferentes dos POSIX e os caminhos do Mac OS 9 são diferentes dos caminhos do RISC OS são diferentes ...

Se for um aplicativo da Web em que o nome do arquivo possa vir de plataformas diferentes, não há uma solução. No entanto, uma facada razoável é usar '\' (Windows) e '/' (Linux / Unix / Mac e também uma alternativa no Windows) como separadores de caminho. Aqui está uma versão que não é RegExp para diversão extra:

var leafname= pathname.split('\\').pop().split('/').pop();
bobince
fonte
Você pode adicionar o MacOS clássico (<= 9) usado separadores de dois pontos (:), mas não conheço nenhum navegador que ainda esteja em uso que não converteu os caminhos do MacOS em caminhos POSIX no formato de arquivo : ///path/to/file.ext
eyelidlessness
4
Você pode usar pop () em vez de reverse () [0]. Ele também modifica a matriz original, mas tudo bem no seu caso.
Chetan Sastry
Gostaria de saber como podemos criar uma contrapartida para obter apenas o caminho.
Todd Horst
Algo 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
A nomeação " nome da folha " é derivada do nome da estrutura de diretório / arquivo "Árvore", a primeira coisa que a árvore faz é raiz , as últimas são as folhas => nome do arquivo é a última coisa no caminho da árvore => folha :-)
jave. web
29

Ates, sua solução não protege contra uma string vazia como entrada. Nesse caso, ele falha com TypeError: /([^(\\|\/|\:)]+)$/.exec(fullPath) has no properties.

bobince, aqui está uma versão do nickf que lida com delimitadores de caminho DOS, POSIX e HFS (e cadeias de caracteres vazias):

return fullPath.replace(/^.*(\\|\/|\:)/, '');
user129661
fonte
4
se estamos escrevendo esse código JS em PHP, precisamos adicionar um \ \ extra para cada \
Lenin Raj Rajasekaran
17

A seguinte linha de código JavaScript fornecerá o nome do arquivo.

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

Não é mais conciso do que a resposta de nickf , mas esta "extrai" diretamente a resposta em vez de substituir partes indesejadas por uma string vazia:

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

Uma pergunta que faz "obter nome do arquivo sem extensão" se refere aqui, mas não há solução para isso. Aqui está a solução modificada da solução de Bobbie.

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

Outro

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

Aqui, split tem uma expressão regular com uma classe de caracteres.
Os dois caracteres precisam ser escapados com '\'

Ou use a matriz para dividir

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

Seria o caminho para empurrar dinamicamente mais separadores em uma matriz, se necessário.
Se fullPathfor explicitamente definido por uma string no seu código, ele precisará escapar da barra invertida !
Gostar"C:\\Documents and Settings\\img\\recycled log.jpg"


fonte
3

Eu uso:

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

Ele substitui o último \e também trabalha com pastas.

pomber
fonte
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
fonte
1

A resposta completa é:

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

Pouca função a ser incluída no seu projeto para determinar o nome do arquivo a partir de um caminho completo para Windows, bem como dos caminhos absolutos do GNU / Linux e 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
fonte
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
fonte
1
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.
Ferrybig
0

Script com êxito para sua pergunta, Teste completo

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

Essa solução é muito mais simples e genérica, tanto para 'nome do arquivo' quanto 'caminho'.

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
fonte
A qualidade de uma resposta pode ser melhorada adicionando algumas explicações ao seu código. Algumas pessoas que buscam essa resposta podem ser novas na codificação ou em expressões regulares, e um pouco de texto para contextualizar ajudará bastante no entendimento.
jmarkmurphy
espero que este caminho é melhor :)
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(".") );
}
Tomas
fonte
-3

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

shriniket
fonte