我需要一个简短的基本名称功能(单线程?)用于Javascript:
basename("/a/folder/file.a.ext") -> "file.a"
basename("/a/folder/file.ext") -> "file"
basename("/a/folder/file") -> "file"
那应该剥离路径和任何扩展名。
更新: 对于开头的点将很好地视为“特殊”文件
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
答案 0 :(得分:65)
function baseName(str)
{
var base = new String(str).substring(str.lastIndexOf('/') + 1);
if(base.lastIndexOf(".") != -1)
base = base.substring(0, base.lastIndexOf("."));
return base;
}
如果您可以同时使用/
和\
作为分隔符,则必须更改代码以再添加一行
答案 1 :(得分:61)
function basename(path) {
return path.split('/').reverse()[0];
}
将路径分解为组件目录和文件名,然后返回最后一块(文件名),这是该数组的最后一个元素。
答案 2 :(得分:19)
上述任何一项工作虽然他们不尊重速度/记忆: - )。
更快/更简单的实现应该使用尽可能少的函数/操作。 RegExp是一个糟糕的选择,因为它实际上可以实现相同的结果但是更容易消耗大量资源。
当您想要包含扩展名的文件名(实际上这是基本名称的正式定义)时的实现:
function basename(str, sep) {
return str.substr(str.lastIndexOf(sep) + 1);
}
如果你需要一个自定义基本名称实现,我必须删除扩展名,我建议使用特定的扩展名剥离函数,你可以随时调用它。
function strip_extension(str) {
return str.substr(0,str.lastIndexOf('.'));
}
用法示例:
basename('file.txt','/'); // real basename
strip_extension(basename('file.txt','/')); // custom basename
它们是分开的,您可以将它们组合起来以获得3种不同的东西:剥离扩展,获取实名,获取自定义基本名称。我认为它比其他方法更优雅。
答案 3 :(得分:11)
如果可以,也许尝试使用现有的包。 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);
答案 4 :(得分:6)
basename = function(path) {
return path.replace(/.*\/|\.[^.]*$/g, '');
}
替换以斜线.*\/
或点结尾的任何内容 - 一些非圆点 - 结束\.[^.]*$
没有任何内容
答案 5 :(得分:3)
使用现代(2020)js代码:
function basename (path) {
return path.substring(path.lastIndexOf('/') + 1)
}
console.log(basename('/home/user/file.txt'))
答案 6 :(得分:2)
就像@ 3DFace评论说的那样:
path.split(/[\\/]/).pop(); // works with both separators
或者如果你喜欢原型:
String.prototype.basename = function(sep) {
sep = sep || '\\/';
return this.split(new RegExp("["+sep+"]")).pop();
}
测试:
var str = "http://stackoverflow.com/questions/3820381/need-a-basename-function-in-javascript";
alert(str.basename());
将返回" need-a-basename-function-in-javascript"。
享受!
答案 7 :(得分:1)
答案 8 :(得分:1)
快速,不带正则表达式,适用于路径类型“ /”和“ \”。同时获取扩展名:
function baseName(str)
{
let li = Math.max(str.lastIndexOf('/'), str.lastIndexOf('\\'));
return new String(str).substring(li + 1);
}
答案 9 :(得分:1)
与上面提供的错误信息相反,正则表达式非常有效。需要注意的是,如果可能的话,他们应该处于一个位置,以便在程序的生命周期中编译一次。
这是一个提供 dirname 和 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];
}
至于性能,我还没有测量过,但是我希望这个解决方案与本页面上其他解决方案的速度相同,但这个解决方案做得更多。帮助实际表现的事实是rx1
将匹配大多数实际路径,因此很少执行rx2
。
这是一些测试代码。
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));
以下是测试代码的结果:
# 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"。 Node' path.dirname()"功能准确地模仿" bash"贝壳" dirname,"但这样好吗?这就是它的作用:
'.'
(空字符串)时生成path==""
(点)。 '.'
时生成path=="just_one_word"
(点)。 '.'
时生成path=="dir_no_file/"
(点)。我更喜欢上面定义的函数的结果。
答案 10 :(得分:1)
function basename(url){
return ((url=/(([^\/\\\.#\? ]+)(\.\w+)*)([?#].+)?$/.exec(url))!= null)? url[2]: '';
}
答案 11 :(得分:0)
如果您的原始字符串或文本文件包含单个反斜杠字符,则可以使用' \'来找到它。 在我的情况下,我使用javascript找到" \ N"的索引。从文本文件。和str.indexOf(' \ N');帮我找到从源文件中读取的原始字符串中的\ N. 希望它有所帮助。
答案 12 :(得分:0)
<强>更新强>
使用前向/
和反斜杠\
单一或双精的改进版本表示以下任一项
\\path\\to\\file
\path\to\file
//path//to//file
/path/to/file
http://url/path/file.ext
http://url/path/file
请参阅下面的工作演示
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>');
});
&#13;
<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>
&#13;
更简单的解决方案可能是
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
答案 13 :(得分:0)
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];}
答案 14 :(得分:0)
使用ES6箭头功能漂亮地一行:
var basename = name => {return /([^\/]*)\.[^.]*$/gm.exec(name)[1];}
答案 15 :(得分:0)
这是我在基本js文件中使用的实现。
// BASENAME
Window.basename = function() {
var basename = window.location.pathname.split(/[\\/]/);
return basename.pop() || basename.pop();
}
答案 16 :(得分:0)
基本名称和目录名称的JavaScript函数:
line = "\t".join(["{}"] * len(records[0]))
f = IteratorFile(line.format(*list(r.values())) for r in records)
示例:
function basename(path) {
return path.replace(/.*\//, '');
}
function dirname(path) {
return path.match(/.*\//);
}
请参见reference。
答案 17 :(得分:0)
basename
实现尽管有所有答案,但我仍然必须制定符合以下条件的自己的解决方案:
path.basename
不会这样做)/
和\
)a/b\c
(这与Node的实现不同,Node的实现改为尊重底层系统的分隔符)getBaseName('a/b/c/') === 'c'
)结尾,则不会返回空路径(确保在运行代码段之前打开控制台)
/**
* Flexible `basename` implementation
* @see https://stackoverflow.com/a/59907288/2228771
*/
function getBasename(path) {
// make sure the basename is not empty, if string ends with separator
let end = path.length-1;
while (path[end] === '/' || path[end] === '\\') {
--end;
}
// support mixing of Win + Unix path separators
const i1 = path.lastIndexOf('/', end);
const i2 = path.lastIndexOf('\\', end);
let start;
if (i1 === -1) {
if (i2 === -1) {
// no separator in the whole thing
return path;
}
start = i2;
}
else if (i2 === -1) {
start = i1;
}
else {
start = Math.max(i1, i2);
}
return path.substring(start+1, end+1);
}
// tests
console.table([
['a/b/c', 'c'],
['a/b/c//', 'c'],
['a\\b\\c', 'c'],
['a\\b\\c\\', 'c'],
['a\\b\\c/', 'c'],
['a/b/c\\', 'c'],
['c', 'c']
].map(([input, expected]) => {
const result = getBasename(input);
return {
input,
result,
expected,
good: result === expected ? '✅' : '❌'
};
}));
答案 18 :(得分:0)
使用正则表达式非常简单:
function basename(input) {
return input.split(/\.[^.]+$/)[0];
}
说明:
匹配单个点字符,后跟除点([^.]
)之外的任何字符,一次或多次(+
),绑定到字符串的末尾($
)
然后根据此匹配条件拆分字符串,并返回第一个结果(即匹配前的所有内容)。
[编辑] D'哦。误读了这个问题 - 他也希望脱离这条道路。哦,无论如何,这回答了一半问题。