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

Javascript 从单个正则表达式匹配文件名和文件扩展名,javascript,jquery,regex,Javascript,Jquery,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); //

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

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()会转义文件路径中的反斜杠,这让我开始感到困惑:)

/^.*\/(.*)?(.*)$/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 regexAll = /[^\\]*\.(\w+)$/;
那你就可以了

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

可以在正则表达式中使用组来执行以下操作:

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

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

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

^([\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]

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

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

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

一次拿一块:
^

锚定到字符串的开头(以避免部分匹配)

(.*)

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

(\。

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

[^.]*

定义字符集
[]
。通过指定这是一个反向字符集来匹配不在该集中的字符。
^
。匹配0个或多个非
字符以获取文件扩展名的其余部分
*
。我们这样指定它,以便它在早期文件名(如
foo.bar.baz
)上不匹配,错误地给出了超过on的扩展名e点在它的
.bar.baz
中,而不仅仅是
.baz
不需要在
[]
内转义,因为所有内容(除了
^
)都是字符集中的文本

)?

结束第二个捕获组
,并指出整个组是可选的
,因为它可能没有扩展名

$

锚定到字符串的末尾(同样,避免部分匹配)

如果您使用的是ES6,您甚至可以使用destructing在一行中获取结果:
[,文件名,扩展名]=/^(.*)(\.[^.]*)?$/.exec('foo.bar.baz');
文件名为
'foo.bar'
,扩展名为
'.baz'

'foo'
给出了
'foo'和'

'foo.
给出
'foo'
'.

'.js'
给出了
'
'.js'
(?!\w+)(\w+)(\s)


查找一个或多个单词
\w+
,否定
(?!)
,使该单词不显示在结果上,指定分隔符
,查找第一个单词
(\w+
),并忽略可能出现的空格
(\s)后面的单词

我更像是一个.net正则表达式的家伙,但你不缺少第一个捕获组吗?@rtpHarry:整个匹配(组0)是文件名(包括扩展名),第一个捕获组(组1)是扩展名。他需要文件名,而不是整个路径。@Ademiban:我不这么认为。他想要和他现在的代码一样的结果,但是在一个正则表达式中完成所有事情。我更像是一个.net正则表达式的家伙,但是你没有错过第一个捕获组吗?你是对的。我刚刚对它进行了测试,文档对此有点混乱:PYour的代码以前是正确的,现在已经损坏了。如果您只有一个捕获组,
匹配项[2]
应该来自哪里?啊,是的,忘记了第一个捕获组。感谢您的提醒。如果使用
'/tmp/myFile.txt'