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?

Yogi Yang 007
la source

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);
}
Ian Oxley
la source
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"

VallaDanger
la source
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;
Maxime Schoeni
la source
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
Uchenna
la source
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;
Xedret
la source
8
var pieces = str.split('\\');
var filename = pieces[pieces.length-1];
TM.
la source
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];
vog
la source
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.

Yéti
la source
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>
DxTx
la source
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?

Jon Watte
la source
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

Mikel
la source
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
Luca C.
la source
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>
sigi
la source
-2

Si vous utilisez jQuery alors

$("#fileupload").val();
Rajat Bansal
la source
val () renverrait en fait le chemin complet du fichier, ce qu'il ne veut pas.
FabricioG