繁体   English   中英

从单个正则表达式匹配文件名和文件扩展名

[英]Match filename and file extension from single Regex

我相信这一定很容易,但我正在努力......

var regexFileName = /[^\\]*$/; // match filename
var regexFileExtension = /(\w+)$/; // match file extension

function displayUpload() {
    var path = $el.val(); //This is a file input
    var filename = path.match(regexFileName); // returns  file name
    var extension = filename[0].match(regexFileExtension); // returns extension

    console.log("The filename is " + filename[0]);
    console.log("The extension is " + extension[0]);
}

上面的函数工作正常,但我确信必须可以通过引用使用 .match() 方法返回的数组的不同部分,使用单个正则表达式来实现。 我试过结合这些正则表达式但没有成功。

另外,我没有在示例中使用字符串来测试它,因为 console.log() 转义了文件路径中的反斜杠,它开始让我感到困惑:)

假设所有文件都有扩展名,您可以使用

var regexAll = /[^\\]*\.(\w+)$/;

然后你可以做

var total = path.match(regexAll);
var filename = total[0];
var extension = total[1];

/^.*\\/(.*)\\.?(.*)$/g后面的第一组是你的文件名,第二组是扩展名。

var myString = "filePath/long/path/myfile.even.with.dotes.TXT";
var myRegexp = /^.*\/(.*)\.(.*)$/g;
var match = myRegexp.exec(myString);
alert(match[1]);  // myfile.even.with.dotes
alert(match[2]);  // TXT

即使您的文件名包含多个点或根本不包含点(没有扩展名),这也有效。
编辑:
这是针对 linux,对于 windows 使用这个/^.*\\\\(.*)\\.?(.*)$/g (在 linux 目录分隔符是/在 windows 是\\

为此,您可以在正则表达式中使用组:

var regex = /^([^\\]*)\.(\w+)$/;
var matches = filename.match(regex);

if (matches) {
    var filename = matches[1];
    var extension = matches[2];
}

这甚至会识别/home/someUser/.aaa/.bb.c

function splitPathFileExtension(path){
    var parsed = path.match(/^(.*\/)(.*)\.(.*)$/);
    return [parsed[1], parsed[2], parsed[3]];
}

我知道这是一个老问题,但这里有另一种解决方案,它可以处理名称中的多个点,也可以在根本没有扩展名(或只有“.”的扩展名)时处理:
/^(.*?)(\\.[^.]*)?$/

一次取一块:
^
锚定到字符串的开头(以避免部分匹配)

(.*?)
匹配任何字符. , 0 次或更多次* , 懒惰? (如果后面的可选扩展名可以匹配,不要只抓取它们),并将它们放在第一个捕获组( )

(\\.
使用(为扩展启动第二个捕获组。该组以文字.字符开头(我们用\\转义,这样.不会被解释为“匹配任何字符”)。

[^.]*
定义一个字符集[] 通过指定这是一个倒置字符集^来匹配不在集合中的字符。 匹配 0 个或多个非. 字符以获取文件扩展名的其余部分* 我们以这种方式指定它,这样它就不会与foo.bar.baz文件名早期匹配,错误地给出了一个包含多个点的扩展名.bar.baz而不仅仅是.baz . 不需要在[]内转义,因为所有内容(除了^ )都是字符集中的文字。

)?
结束第二个捕获组)并表明整个组是可选的? ,因为它可能没有扩展名。

$
锚定到字符串的末尾(再次,避免部分匹配)

如果您使用的是 ES6,您甚至可以使用析构来获取 1 行中的结果:
[,filename, extension] = /^(.*?)(\\.[^.]*)?$/.exec('foo.bar.baz'); 它给出的文件名是'foo.bar' ,扩展名是'.baz'
'foo'给出'foo' and ''
'foo.' 给出'foo''.'
'.js'给出'''.js'

我认为这是一个更好的方法,因为只匹配有效的目录、文件名和扩展名。 并对路径、文件名和文件扩展名进行分组。 并且也仅适用于空路径文件名。

^([\w\/]*?)([\w\.]*)\.(\w)$

测试用例

the/p0090Aath/fav.min.icon.png
the/p0090Aath/fav.min.icon.html
the/p009_0Aath/fav.m45in.icon.css
fav.m45in.icon.css
favicon.ico

输出

[the/p0090Aath/][fav.min.icon][png]
[the/p0090Aath/][fav.min.icon][html]
[the/p009_0Aath/][fav.m45in.icon][css]
[][fav.m45in.icon][css]
[][favicon][ico]

(?!\\w+).(\\w+)(\\s)

查找一个或多个单词 (s) \\w+ ,否定(?! )以便结果中不显示单词 (s),指定分隔符. , 找到第一个单词(\\w+)并忽略可能的空格(\\s)之后的单词

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM