在Javascript中需要一个基本名称函数

我需要一个简短的basename函数(one-liner?)用于Javascript:

basename("/a/folder/file.a.ext") -> "file.a" basename("/a/folder/file.ext") -> "file" basename("/a/folder/file") -> "file" 

这应该剥离path和任何扩展名。

更新:在开始点将是很好的待遇作为“特殊”的文件

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

如果您可以同时拥有/\分隔符,则必须更改代码以再添加一行

 function basename(path) { return path.split('/').reverse()[0]; } 

将path分解为组件目录和文件名,然后返回数组的最后一个元素(文件名)。

以上任何一项作品虽然都不尊重速度/内存:-)。

更快/更简单的实现应该使用尽可能less的function/操作。 RegExp是一个不错的select,因为它实际上我们可以达到相同的结果,但是更容易消耗大量的资源。

一个实现,当你想要的文件名,包括扩展名(实际上这是基本名称的真正定义 ):

 function basename(str, sep) { return str.substr(str.lastIndexOf(sep) + 1); } 

如果你需要一个自定义的基本实现 ,也必须剥离扩展我会build议,而不是一个特定的扩展剥离function的情况下,你可以随时调用它。

 function strip_extension(str) { return str.substr(0,str.lastIndexOf('.')); } 

用法示例:

 basename('file.txt','/'); // real basename strip_extension(basename('file.txt','/')); // custom basename 

他们是分开的,你可以结合他们获得3个不同的东西:剥离延伸,获得真正的基础名称,得到您的自定义基准名称。 我认为这比其他方法更优雅。

也许尝试使用现有的软件包,如果可以的话。 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' 

其他例子:

 var pathString = path.dirname(str); var fileNameStringWithExtention = path.basename(str); var fullPathAndFileNameString = path.join(pathString, fileNameString); 
  basename = function(path) { return path.replace(/.*\/|\.[^.]*$/g, ''); } 

replace任何以斜线结尾的东西.*\/或点 – 一些非点 – 结束\.[^.]*$没有任何东西

 function basename(url){ return ((url=/(([^\/\\\.#\? ]+)(\.\w+)*)([?#].+)?$/.exec(url))!= null)? url[2]: ''; } 
 my_basename('http://www.example.com/dir/file.php?param1=blabla#cprod', '/', '?'); // returns: file.php 

码:

 function my_basename(str, DirSeparator, FileSeparator) { var x= str.split(DirSeparator); return x[x.length-1].split(FileSeparator)[0];} 

就像@ 3DFace所评论的:

 path.split(/[\\/]/).pop(); // works with both separators 

或者如果你喜欢原型:

 String.prototype.basename = function(sep) { sep = sep || '\\/'; return this.split(new RegExp("["+sep+"]")).pop(); } 

testing:

 var str = "http://stackoverflow.com/questions/3820381/need-a-basename-function-in-javascript"; alert(str.basename()); 

将返回“需要一个基本名称 – function的JavaScript”。

请享用!

与上面提供的错误信息相反,正则expression式非常有效。 需要注意的是,如果可能的话,他们应该在一个位置上,以便在程序的整个生命周期中只编译一次。

这是一个解决scheme,同时提供dirnamebasename

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

至于性能方面,我还没有测算出来,但是我希望这个解决scheme和本页面上的其他解决scheme在同一个范围内,但是这个解决scheme做的更多。 帮助现实世界的performance是rx2将匹配大多数实际path,所以很less执行rx2

这里是一些testing代码。

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

这里是testing代码产生的结果:

 # 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 

顺便说一句,“节点”有一个名为“path”,具有“dirname”和“basename”的内置模块。 节点的“path.dirname()”函数准确地模仿了“bash”shell的“dirname”的行为,但是这样好吗? 以下是它的作用:

  1. 产生'.' (点)当path=="" (空string)。
  2. 产生'.' (点)当path=="just_one_word"
  3. 产生'.' (点)当path=="dir_no_file/"

我更喜欢上面定义的函数的结果。

使用正则expression式相当简单:

 function basename(input) { return input.split(/\.[^.]+$/)[0]; } 

说明:

匹配单个点字符,后面跟除点( [^.] )之外的任何字符,一次或多次( + ),绑定到string( $ )的末尾。

然后根据这个匹配条件分割string,并返回第一个结果(即匹配前的所有内容)。

[编辑]哦。 误解了这个问题 – 他也想剥离这条路。 噢,无论如何,这回答了一半的问题。

另一个好方法是

 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 } 

来自: http : //locutus.io/php/filesystem/basename/

如果您的原始string或文本文件包含单个反斜杠字符,则可以使用'\'来查找它。 在我的情况下,我正在使用JavaScript从文本文件中find“\ N”的索引。 和str.indexOf('\ N'); 帮助我find从源文件中读取的原始string\ N。 希望能帮助到你。

更简单的解决scheme可以是

 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 

工作示例: https : //jsfiddle.net/Smartik/2c20q0ak/1/