Javascript - Comment extraire un nom de fichier d'un contrôle d'entrée de fichier


117

Lorsqu'un utilisateur sélectionne un fichier dans une page Web, je souhaite pouvoir extraire uniquement le nom du fichier.

J'ai essayé la fonction str.search mais cela semble échouer lorsque le nom du fichier ressemble à ceci: c: \ uploads \ ilike.this.file.jpg .

Comment pouvons-nous extraire uniquement le nom du fichier sans extension?

Réponses:


127

En supposant que votre <input type = "file"> a un identifiant de téléchargement, cela devrait, espérons-le, faire l'affaire:

var fullPath = document.getElementById('upload').value;
if (fullPath) {
    var startIndex = (fullPath.indexOf('\\') >= 0 ? fullPath.lastIndexOf('\\') : fullPath.lastIndexOf('/'));
    var filename = fullPath.substring(startIndex);
    if (filename.indexOf('\\') === 0 || filename.indexOf('/') === 0) {
        filename = filename.substring(1);
    }
    alert(filename);
}

Merci, cela semble bien fonctionner, mais je veux juste un nom de fichier sans extension. Comment puis-je faire cela dans le code ci-dessus.
Yogi Yang 007

J'ai ajouté ces deux lignes de code pour extraire uniquement le nom du fichier sans extension: "filename = filename.substring (0, filename.length-4); filename = filename.toLowerCase ();"
Yogi Yang 007

13
Non, vous ne voulez pas le faire de cette façon dit Yogi Yang. Utilisez plutôt: filename = filename.substring(0, filename.lastIndexOf('.'));Parce que son chemin échouera avec des extensions de plus de 3 caractères, donc: .html, .jpeg etc.
Yeti

1
comment obtenir les noms de fichiers en cas de sélection de fichiers multiples?
avngr

Pourquoi ne pas simplement calculer startIndex comme ça? var startIndex = Math.max(fullPath.lastIndexOf('\\'), fullPath.lastIndexOf('/')) + 1;
nollidge

196

Pour diviser la chaîne ({filepath} / {filename}) et obtenir le nom du fichier, vous pouvez utiliser quelque chose comme ceci:

str.split(/(\\|\/)/g).pop()

"La méthode pop supprime le dernier élément d'un tableau et renvoie cette valeur à l'appelant."
Réseau de développeurs Mozilla

Exemple:

de: "/home/user/file.txt".split(/(\\|\/)/g).pop()

vous obtenez: "file.txt"


5
Vous pouvez également le faire uniquement avec des expressions rationnelles et sans aucune opération de tableau:var filename = filepath.replace(/^.*?([^\\\/]*)$/, '$1');
vog

1
La réponse de vog est vraiment proche de la réponse précise à 100% à la question (sauf qu'il faut supprimer l'extension.) Un nom de fichier n'est pas différent de toute autre chaîne.
Jon Watte

1
La regex fractionnée peut être raccourcie en [\\/]. De plus, il a également été demandé de supprimer l'extension de fichier. Pour une solution complète, voir: stackoverflow.com/a/32156800/19163
vog

multiplateforme, concis. Génial.
Marc

Excellente solution, je ne comprends pas comment ça marche et c'est pourquoi je l'aime plus!
Chatoxz

92

De nos jours, il existe un moyen beaucoup plus simple:

var fileInput = document.getElementById('upload');   
var filename = fileInput.files[0].name;

5
Vérifiez fileInput.files.lengthavant d'appeler .name, au cas où l'utilisateur clique sur Annuler.
marcovtwout

29

Très simple

let file = $("#fileupload")[0].files[0]; 
file.name

Dans le cas où vous utilisez TypeScript alors son $ ("# fileupload") [0] ["files"] [0];
Morvael

18

En supposant:

<input type="file" name="file1" id="theFile">

Le JavaScript serait:

var fileName = document.getElementById('theFile').files[0].name;

8
var pieces = str.split('\\');
var filename = pieces[pieces.length-1];

Cela suppose que l'utilisateur exécute Windows. D'autres systèmes d'exploitation utilisent des séparateurs de chemins de fichiers différents.
Quentin

Auriez-vous besoin de vérifier le caractère «/» également pour les utilisateurs non-Windows, par exemple if (! Pieces) {str.split ('/'); }? Belle solution simple cependant +1
Ian Oxley

IIRC, IE est le seul navigateur qui donne de toute façon le chemin complet du fichier ... Vous n'aurez pas besoin de diviser sur d'autres navigateurs comme Firefox, donc cela fonctionne toujours. Bien que j'admette que je n'ai pas essayé TOUS les navigateurs linux / unix.
TM.

6
str.split (/ (\\ | \ /) / g); pour windows et * nix
Tracker1

@TM. Chrome utilise une fausse variable de chemin pour la sécurité, ce qui est moche; iirc c'est différent selon le système d'exploitation sur lequel vous vous trouvez.
lededje

5

Je suppose que vous voulez supprimer toutes les extensions, c'est- /tmp/test/somefile.tar.gzà- dire à somefile.

Approche directe avec regex:

var filename = filepath.match(/^.*?([^\\/.]*)[^\\/]*$/)[1];

Approche alternative avec regex et opération de tableau:

var filename = filepath.split(/[\\/]/g).pop().split('.')[0];

1
Cela ne supprime pas l'extension, comme demandé.
Jon Watte

Fixé. Merci pour l'indice!
vog le

4

Je viens d'en faire ma propre version. Ma fonction peut être utilisée pour en extraire tout ce que vous voulez, si vous n'avez pas besoin de tout cela, vous pouvez facilement supprimer du code.

<html>
<body>
<script type="text/javascript">
// Useful function to separate path name and extension from full path string
function pathToFile(str)
{
    var nOffset = Math.max(0, Math.max(str.lastIndexOf('\\'), str.lastIndexOf('/')));
    var eOffset = str.lastIndexOf('.');
    if(eOffset < 0 && eOffset < nOffset)
    {
        eOffset = str.length;
    }
    return {isDirectory: eOffset === str.length, // Optionally: && nOffset+1 === str.length if trailing slash means dir, and otherwise always file
            path: str.substring(0, nOffset),
            name: str.substring(nOffset > 0 ? nOffset + 1 : nOffset, eOffset),
            extension: str.substring(eOffset > 0 ? eOffset + 1 : eOffset, str.length)};
}

// Testing the function
var testcases = [
    "C:\\blabla\\blaeobuaeu\\testcase1.jpeg",
    "/tmp/blabla/testcase2.png",
    "testcase3.htm",
    "C:\\Testcase4", "/dir.with.dots/fileWithoutDots",
    "/dir.with.dots/another.dir/"
];
for(var i=0;i<testcases.length;i++)
{
    var file = pathToFile(testcases[i]);
    document.write("- " + (file.isDirectory ? "Directory" : "File") + " with name '" + file.name + "' has extension: '" + file.extension + "' is in directory: '" + file.path + "'<br />");
}
</script>
</body>
</html>

Sortira ce qui suit:

  • Le fichier avec le nom 'testcase1' a l'extension: 'jpeg' est dans le répertoire: 'C: \ blabla \ blaeobuaeu'
  • Le fichier avec le nom 'testcase2' a l'extension: 'png' est dans le répertoire: '/ tmp / blabla'
  • Le fichier avec le nom 'testcase3' a l'extension: 'htm' est dans le répertoire: ''
  • Le répertoire avec le nom 'Testcase4' a l'extension: '' est dans le répertoire: 'C:'
  • Le répertoire avec le nom 'fileWithoutDots' a l'extension: '' est dans le répertoire: '/dir.with.dots'
  • Le répertoire avec le nom «» a l'extension: «» est dans le répertoire: «/dir.with.dots/another.dir»

Avec && nOffset+1 === str.lengthajouté à isDirectory:

  • Le fichier avec le nom 'testcase1' a l'extension: 'jpeg' est dans le répertoire: 'C: \ blabla \ blaeobuaeu'
  • Le fichier avec le nom 'testcase2' a l'extension: 'png' est dans le répertoire: '/ tmp / blabla'
  • Le fichier avec le nom 'testcase3' a l'extension: 'htm' est dans le répertoire: ''
  • Le répertoire avec le nom 'Testcase4' a l'extension: '' est dans le répertoire: 'C:'
  • Le répertoire avec le nom 'fileWithoutDots' a l'extension: '' est dans le répertoire: '/dir.with.dots'
  • Le répertoire avec le nom «» a l'extension: «» est dans le répertoire: «/dir.with.dots/another.dir»

Compte tenu des cas de test, vous pouvez voir que cette fonction fonctionne de manière assez robuste par rapport aux autres méthodes proposées ici.

Remarque pour les débutants à propos de \\: \ est un caractère d'échappement, par exemple \ n signifie une nouvelle ligne et \ ta tab. Pour permettre d'écrire \ n, vous devez en fait taper \\ n.


1
Faites attention à ce chemin: dir.with.dots / fileWithoutDots car vous obtiendrez eOffset inférieur à nOffset et confondrez les expressions d'extraction.
Jesse Chisholm

Ouais, réparé. Maintenant, cela devrait fonctionner correctement aussi (ajouté && eOffset < nOffset).
Yeti

2

Entrée : C:\path\Filename.ext
Sortie :Filename

Dans le code HTML, définissez la onChangevaleur File comme ceci ...

<input type="file" name="formdata" id="formdata" onchange="setfilename(this.value)"/>

En supposant que votre identifiant de champ de texte est 'wpName' ...

<input type="text" name="wpName" id="wpName">

JavaScript

<script>
  function setfilename(val)
  {
    filename = val.split('\\').pop().split('/').pop();
    filename = filename.substring(0, filename.lastIndexOf('.'));
    document.getElementById('wpName').value = filename;
  }
</script>

1

Aucune des réponses fortement votées ne fournit réellement "juste le nom de fichier sans extension" et les autres solutions sont beaucoup trop de code pour un travail aussi simple.

Je pense que cela devrait être une ligne unique pour tout programmeur JavaScript. C'est une expression régulière très simple:

function basename(prevname) {
    return prevname.replace(/^(.*[/\\])?/, '').replace(/(\.[^.]*)$/, '');
}

Commencez par supprimer tout élément jusqu'à la dernière barre oblique, le cas échéant.

Ensuite, dépouillez quoi que ce soit après les dernières règles, le cas échéant.

C'est simple, c'est robuste, il met en œuvre exactement ce qui est demandé. Est-ce que je manque quelque chose?


1
"une expression régulière très simple" ... En fait, ce sont deux expressions régulières. :-) Voir ma réponse pour une solution single-regex.
vog le

Oui, il y a aussi une réécriture évidente pour regrouper ces deux expressions régulières dans une seule expression régulière en utilisant l'opérateur pipe (|). Je pense que le code tel qu'il est écrit est plus clair, mais il parcourt la chaîne deux fois, ce qui serait un problème si la chaîne est généralement assez longue. (Les chemins de fichiers ne le sont généralement pas, mais peuvent l'être.)
Jon Watte

1
J'étais juste pinailleur. Veuillez ne pas prendre cela au sérieux. Il n'y a pas besoin d'optimiser, toutes les solutions proposées sont plus que suffisamment rapides. Les chemins de fichiers très longs sont toujours des kilo-octets, pas des gigaoctets. Et cette fonction sera déclenchée une fois par téléchargement de fichier, pas 1000x dans un lot. Les seules choses qui comptent ici sont l'exactitude et la clarté du code.
vog le

1
// HTML
<input type="file" onchange="getFileName(this)">

// JS
function getFileName(input) {
    console.log(input.files[0].name) // With extension
    console.log(input.files[0].name.replace(/\.[^/.]+$/, '')) // Without extension
}

Comment supprimer l'extension


1
Cela manque une partie importante de la question, "extraire uniquement le nom du fichier sans extension". Il est utile de lire attentivement la question avant de sauter pour y répondre.
zeh

1
var path = document.getElementById('upload').value;//take path
var tokens= path.split('\\');//split path
var filename = tokens[tokens.length-1];//take file name

0

Aucune des réponses ci-dessus n'a fonctionné pour moi, voici ma solution qui met à jour une entrée désactivée avec le nom de fichier:

<script type="text/javascript"> 
  document.getElementById('img_name').onchange = function () {
  var filePath = this.value;
    if (filePath) {
      var fileName = filePath.replace(/^.*?([^\\\/]*)$/, '$1');
      document.getElementById('img_name_input').value = fileName;
    }
  };
</script>

-2

Si vous utilisez jQuery alors

$("#fileupload").val();

val () renverrait en fait le chemin complet du fichier, ce qu'il ne veut pas.
FabricioG
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.