J'ai besoin d'une fonction de nom de base courte (one-liner?) Pour Javascript:
basename("/a/folder/file.a.ext") -> "file.a"
basename("/a/folder/file.ext") -> "file"
basename("/a/folder/file") -> "file"
Cela devrait dépouiller le chemin et toute extension.
Mise à jour: Pour les points au début, il serait agréable de traiter les fichiers "spéciaux"
basename("/a/folder/.file.a.ext") -> ".file.a"
basename("/a/folder/.file.ext") -> ".file"
basename("/a/folder/.file") -> ".file" # empty is Ok
basename("/a/folder/.fil") -> ".fil" # empty is Ok
basename("/a/folder/.file..a..") -> # does'nt matter
function baseName(str)
{
var base = new String(str).substring(str.lastIndexOf('/') + 1);
if(base.lastIndexOf(".") != -1)
base = base.substring(0, base.lastIndexOf("."));
return base;
}
Si vous pouvez utiliser à la fois /
et \
comme séparateurs, vous devez modifier le code pour ajouter une ligne supplémentaire.
function basename(path) {
return path.split('/').reverse()[0];
}
Divise le chemin en répertoires de composants et nom_fichier renvoie ensuite le dernier élément (le nom_fichier) qui est le dernier élément du tableau.
Tout ce qui précède fonctionne même s’ils n’ont aucun respect pour la vitesse/la mémoire :-).
Une implémentation plus rapide/plus simple devrait utiliser le moins de fonctions/opérations possible. RegExp est un mauvais choix car il consomme beaucoup de ressources alors qu'en réalité nous pouvons obtenir le même résultat mais plus facilement.
Une implémentation lorsque vous voulez que le nom de fichier comprenne l’extension (il s’agit en fait de la définition authentique du nom de base):
function basename(str, sep) {
return str.substr(str.lastIndexOf(sep) + 1);
}
Si vous avez besoin d'une implémentation personnalisée de nom_base qui doit également effacer l'extension, je vous recommanderais plutôt une fonction spécifique d'élimination d'extension pour ce cas, que vous pourrez appeler à tout moment.
function strip_extension(str) {
return str.substr(0,str.lastIndexOf('.'));
}
Exemple d'utilisation:
basename('file.txt','/'); // real basename
strip_extension(basename('file.txt','/')); // custom basename
Ils sont séparés de telle sorte que vous pouvez les combiner pour obtenir 3 choses différentes: supprimer l’extension, obtenir le nom de base réel, obtenir votre nom de base personnalisé. Je le considère comme une mise en œuvre plus élégante que d’autres approches.
Peut-être essayer d'utiliser les paquets existants si vous le pouvez. http://nodejs.org/api/path.html
var path = require('path');
var str = '/path/to/file/test.html'
var fileNameStringWithoutExtention = path.basename(str, '.html');
// returns 'test'
// let path determine the extension
var fileNameStringWithoutExtention = path.basename(str, path.extname(str));
// returns 'test'
Autres exemples:
var pathString = path.dirname(str);
var fileNameStringWithExtention = path.basename(str);
var fullPathAndFileNameString = path.join(pathString, fileNameString);
basename = function(path) {
return path.replace(/.*\/|\.[^.]*$/g, '');
}
remplace tout ce qui se termine par un slash .*\/
ou un point - certains non-dots - termine \.[^.]*$
par rien
Tout comme @ 3DFace a commenté:
path.split(/[\\/]/).pop(); // works with both separators
Ou si vous aimez les prototypes:
String.prototype.basename = function(sep) {
sep = sep || '\\/';
return this.split(new RegExp("["+sep+"]")).pop();
}
Essai:
var str = "http://stackoverflow.com/questions/3820381/need-a-basename-function-in-javascript";
alert(str.basename());
Renverra "besoin-un-nom-base-fonction-en-JavaScript".
Prendre plaisir!
Une autre bonne solution:
function basename (path, suffix) {
// discuss at: http://locutus.io/php/basename/
// original by: Kevin van Zonneveld (http://kvz.io)
// improved by: Ash Searle (http://hexmen.com/blog/)
// improved by: Lincoln Ramsay
// improved by: djmix
// improved by: Dmitry Gorelenkov
// example 1: basename('/www/site/home.htm', '.htm')
// returns 1: 'home'
// example 2: basename('ecra.php?p=1')
// returns 2: 'ecra.php?p=1'
// example 3: basename('/some/path/')
// returns 3: 'path'
// example 4: basename('/some/path_ext.ext/','.ext')
// returns 4: 'path_ext'
var b = path
var lastChar = b.charAt(b.length - 1)
if (lastChar === '/' || lastChar === '\\') {
b = b.slice(0, -1)
}
b = b.replace(/^.*[\/\\]/g, '')
if (typeof suffix === 'string' && b.substr(b.length - suffix.length) === suffix) {
b = b.substr(0, b.length - suffix.length)
}
return b
}
à partir de: http://locutus.io/php/filesystem/basename/
function basename(url){
return ((url=/(([^\/\\\.#\? ]+)(\.\w+)*)([?#].+)?$/.exec(url))!= null)? url[2]: '';
}
Contrairement aux informations erronées fournies ci-dessus, les expressions régulières sont extrêmement efficaces. La mise en garde est que, lorsque cela est possible, ils devraient être en mesure de compiler exactement une fois dans la vie du programme.
Voici une solution qui donne à la fois dirname et basename .
const rx1 = /(.*)\/+([^/]*)$/; // (dir/) (optional_file)
const rx2 = /()(.*)$/; // () (file)
function dir_and_file(path) {
// result is array with
// [0] original string
// [1] dirname
// [2] filename
return rx1.exec(path) || rx2.exec(path);
}
// Single purpose versions.
function dirname(path) {
return (rx1.exec(path) || rx2.exec(path))[1];
}
function basename(path) {
return (rx1.exec(path) || rx2.exec(path))[2];
}
En ce qui concerne les performances, je ne les ai pas mesurées, mais je m'attends à ce que cette solution soit dans la même plage que la plus rapide des autres sur cette page, mais cette solution en fait plus. Le fait que rx1
corresponde à la plupart des chemins actuels contribue à la performance réelle, si bien que rx2
est rarement exécuté.
Voici un code de test.
function show_dir(parts) {
console.log("Original str :"+parts[0]);
console.log("Directory nm :"+parts[1]);
console.log("File nm :"+parts[2]);
console.log();
}
show_dir(dir_and_file('/absolute_dir/file.txt'));
show_dir(dir_and_file('relative_dir////file.txt'));
show_dir(dir_and_file('dir_no_file/'));
show_dir(dir_and_file('just_one_Word'));
show_dir(dir_and_file('')); // empty string
show_dir(dir_and_file(null));
Et voici ce que le code de test donne:
# Original str :/absolute_dir/file.txt
# Directory nm :/absolute_dir
# File nm :file.txt
#
# Original str :relative_dir////file.txt
# Directory nm :relative_dir
# File nm :file.txt
#
# Original str :dir_no_file/
# Directory nm :dir_no_file
# File nm :
#
# Original str :just_one_Word
# Directory nm :
# File nm :just_one_Word
#
# Original str :
# Directory nm :
# File nm :
#
# Original str :null
# Directory nm :
# File nm :null
A propos, "noeud" a un module intégré appelé "chemin" qui a "dirname" et "basename". La fonction "path.dirname ()" du noeud imite avec précision le comportement du "nom du répertoire" du shell "bash", mais est-ce bon? Voici ce qu'il fait:
'.'
(point) lorsque path==""
(chaîne vide). '.'
(point) lorsque path=="just_one_Word"
. '.'
(point) lorsque path=="dir_no_file/"
.Je préfère les résultats de la fonction définie ci-dessus.
METTRE À JOUR
Une version améliorée qui fonctionne avec forward /
et backslash \
simple ou double signifie l’un des éléments suivants
\\path\\to\\file
\path\to\file
//path//to//file
/path/to/file
http://url/path/file.ext
http://url/path/file
Voir une démo de travail ci-dessous
let urlHelper = {};
urlHelper.basename = (path) => {
let isForwardSlash = path.match(/\/{1,2}/g) !== null;
let isBackSlash = path.match(/\\{1,2}/g) !== null;
if (isForwardSlash) {
return path.split('/').reverse().filter(function(el) {
return el !== '';
})[0];
} else if (isBackSlash) {
return path.split('\\').reverse().filter(function(el) {
return el !== '';
})[0];
}
return path;
};
$('em').each(function() {
var text = $(this).text();
$(this).after(' --> <strong>' + urlHelper.basename(text) + '</strong><br>');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<em>http://folder/subfolder/file.ext</em><br>
<em>http://folder/subfolder/subfolder2</em><br>
<em>/folder/subfolder</em><br>
<em>/file.ext</em><br>
<em>file.ext</em><br>
<em>/folder/subfolder/</em><br>
<em>//folder//subfolder//</em><br>
<em>//folder//subfolder</em><br>
<em>\\folder\\subfolder\\</em><br>
<em>\\folder\\subfolder\\file.ext</em><br>
<em>\folder\subfolder\</em><br>
<em>\\folder\\subfolder</em><br>
<em>\\folder\\subfolder\\file.ext</em><br>
<em>\folder\subfolder</em><br>
Une solution plus simple pourrait être
function basename(path) {
return path.replace(/\/+$/, "").replace( /.*\//, "" );
}
Input basename()
/folder/subfolder/file.ext --> file.ext
/folder/subfolder --> subfolder
/file.ext --> file.ext
file.ext --> file.ext
/folder/subfolder/ --> subfolder
Exemple d'utilisation: https://jsfiddle.net/Smartik/2c20q0ak/1/
si votre chaîne ou votre fichier texte d'origine contient une simple barre oblique inverse, vous pouvez le localiser à l'aide de '\'. Dans mon cas, javascript est utilisé pour trouver l'index de "\ N" à partir d'un fichier texte. et str.indexOf ('\ N'); m'a aidé à localiser le\N à partir de la chaîne d'origine qui est lue à partir du fichier source . espérons que cela aide.
my_basename('http://www.example.com/dir/file.php?param1=blabla#cprod', '/', '?');
// returns: file.php
CODE:
function my_basename(str, DirSeparator, FileSeparator) { var x= str.split(DirSeparator); return x[x.length-1].split(FileSeparator)[0];}
Assez simple avec regex:
function basename(input) {
return input.split(/\.[^.]+$/)[0];
}
Explication:
Correspond à un seul point, suivi de tout caractère à l'exception d'un point ([^.]
), une ou plusieurs fois (+
), lié à la fin de la chaîne ($
).
Il divise ensuite la chaîne en fonction de ce critère de correspondance et renvoie le premier résultat (c'est-à-dire tout ce qui précède la correspondance).
[EDIT] D'oh. Mal interprété la question - il veut aussi dégager le chemin. Oh bien, cela répond quand même à la moitié de la question.