Comment obtenir le nom de fichier à partir d'un chemin complet en utilisant JavaScript?


310

Existe-t-il un moyen d'obtenir la dernière valeur (basée sur le symbole «\») à partir d'un chemin complet?

Exemple:

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

Avec ce cas, je veux juste sortir recycled log.jpgdu chemin complet en JavaScript.

Réponses:


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

Cela gérera les deux chemins \ OR / in


4
Ne fonctionne pas sur MAC OSX, en utilisant le chrome, il échappe au caractère après \
Pankaj Phartiyal

7
Selon ce site, l'utilisation replaceest beaucoup plus lente que substr, ce qui peut être utilisé conjointement avec lastIndexOf('/')+1: jsperf.com/replace-vs-substring
Nate

1
@nickf Nick, je ne sais pas où je vais mal, mais le code ne fonctionne pas pour moi lorsque le chemin du fichier a une seule barre oblique. Fiddle, bien que pour `\\` , cela fonctionne bien.
Shubh

1
Je viens de lancer cela sur ma console, et cela a fonctionné parfaitement pour les barres obliques: "/var/drop/foo/boo/moo.js".replace(/^.*[\\\/]/, '')retoursmoo.js
vikkee

1
@ZloySmiertniy Il y a quelques bons explicateurs regex en ligne. rick.measham.id.au/paste/explain.pl?regex=%2F%5E . *% 5B% 5C% 5C% 5C% 2F% 5D% 2F et regexper.com/#%2F%5E . *% 5B % 5C% 5C% 5C% 2F% 5D% 2F devrait vous aider. (Les liens sont cassés ici, mais copiez-collez dans un onglet et cela fonctionnera)
nickf

115

Pour des raisons de performances, j'ai testé toutes les réponses données ici:

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

Et le gagnant est la réponse de style Split et Pop , Merci à bobince !


4
Par la méta discussion, veuillez ajouter la citation appropriée aux autres réponses. Il serait également utile de mieux expliquer comment vous avez analysé le runtime.
jpmc26

N'hésitez pas à comparer cette version également. Devrait prendre en charge les chemins de fichiers Mac et Windows. path.split(/.*[\/|\\]/)[1];
tfmontague

2
Le test est incorrect. substringTest recherche uniquement la barre oblique, execTest - uniquement la barre oblique inverse tandis que deux autres gèrent les deux barres obliques. Et les résultats réels ne sont plus pertinents (plus). Vérifiez ceci: jsperf.com/name-from-path
Grief

@Grief ce lien n'est plus valide.
paqogomez

88

Dans Node.js, vous pouvez utiliser le module d'analyse de Path ...

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

var filename = path.parse(file).base;
//=> 'file.txt'

14
Si vous utilisez Node.js, vous pouvez simplement utiliser la basenamefonction:path.basename(file)
electrovir

66

De quelle plateforme vient le chemin? Les chemins Windows sont différents des chemins POSIX sont différents de Mac OS 9 Les chemins sont différents de RISC OS Les chemins sont différents ...

S'il s'agit d'une application Web dont le nom de fichier peut provenir de différentes plates-formes, il n'y a pas de solution unique. Cependant, une approche raisonnable consiste à utiliser à la fois «\» (Windows) et «/» (Linux / Unix / Mac et également une alternative sous Windows) comme séparateurs de chemin. Voici une version non RegExp pour plus de plaisir:

var leafname= pathname.split('\\').pop().split('/').pop();

Vous voudrez peut-être ajouter que les séparateurs deux-points classiques de MacOS (<= 9) utilisaient (:), mais je ne connais aucun navigateur qui soit encore utilisé et qui ne traduise pas les chemins MacOS en chemins POSIX sous forme de fichier. : ///path/to/file.ext
eyelidlessness

4
Vous pouvez simplement utiliser pop () au lieu de reverse () [0]. Il modifie également le tableau d'origine, mais ça va dans votre cas.
Chetan Sastry

Je me demande comment nous pouvons créer un homologue pour obtenir exactement le chemin.
Todd Horst du

Quelque chose comme 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 du

La dénomination " nom de feuille " est dérivée du nom de la structure du répertoire / fichier "Arbre", la première chose de l' arbre est racine , les dernières sont les feuilles => le nom du fichier est la dernière chose dans le chemin de l' arbre => feuille :-)
jave. web

29

Ates, votre solution ne protège pas contre une chaîne vide en entrée. Dans ce cas, il échoue avec TypeError: /([^(\\|\/|\:)]+)$/.exec(fullPath) has no properties.

bobince, voici une version de nickf qui gère les délimiteurs de chemin DOS, POSIX et HFS (et les chaînes vides):

return fullPath.replace(/^.*(\\|\/|\:)/, '');

4
si nous écrivons ce code JS en PHP, nous devons ajouter un \ supplémentaire pour chaque \
Lénine Raj Rajasekaran

17

La ligne suivante de code JavaScript vous donnera le nom du fichier.

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

10

Pas plus concis que la réponse de nickf , mais celui-ci "extrait" directement la réponse au lieu de remplacer les parties indésirables par une chaîne vide:

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

8

Une question demandant "obtenir le nom du fichier sans extension" se réfère ici, mais aucune solution pour cela. Voici la solution modifiée de la solution de Bobbie.

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

6

Un autre

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

Ici, split a une expression régulière avec une classe de caractères
Les deux caractères doivent être échappés avec '\'

Ou utilisez un tableau pour diviser

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

Ce serait le moyen de pousser dynamiquement plus de séparateurs dans un tableau, si nécessaire.
Si fullPathest explicitement défini par une chaîne dans votre code, il doit échapper à la barre oblique inverse !
Comme"C:\\Documents and Settings\\img\\recycled log.jpg"


3

J'utilise:

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

Il remplace le dernier \donc il fonctionne également avec les dossiers.


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>

1

La réponse complète est:

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

1

Petite fonction à inclure dans votre projet pour déterminer le nom de fichier à partir d'un chemin complet pour Windows ainsi que des chemins absolus GNU / Linux & 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)
}

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>

1
Bien que cet extrait de code puisse résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question des lecteurs à l'avenir et que ces personnes ne connaissent peut-être pas les raisons de votre suggestion de code.
Ferrybig

0

Script avec succès pour votre question, test complet

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


0

Cette solution est beaucoup plus simple et générique, à la fois pour «nom de fichier» et «chemin».

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

La qualité d'une réponse peut être améliorée en ajoutant des explications à votre code. Certaines personnes à la recherche de cette réponse peuvent être nouvelles dans le codage ou les expressions régulières, et un petit texte pour donner du contexte contribuera grandement à la compréhension.
jmarkmurphy

j'espère que cette voie est meilleure :)
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(".") );
}

-3

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.