Javascript 从单个正则表达式匹配文件名和文件扩展名
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9001557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Match filename and file extension from single Regex
提问by Tom Bates
I'm sure this must be easy enough, but I'm struggling...
我相信这一定很容易,但我正在努力......
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]);
}
The function above works fine, but I'm sure it must be possible to achieve with a single regex, by referencing different parts of the array returned with the .match() method. I've tried combining these regex but without success.
上面的函数工作正常,但我确信必须可以通过引用使用 .match() 方法返回的数组的不同部分,使用单个正则表达式来实现。我试过结合这些正则表达式但没有成功。
Also, I'm not using a string to test it on in the example, as console.log() escapes the backslashes in a filepath and it was starting to confuse me :)
另外,我没有在示例中使用字符串来测试它,因为 console.log() 转义了文件路径中的反斜杠,它开始让我感到困惑:)
采纳答案by Tim Pietzcker
Assuming that all files do have an extension, you could use
假设所有文件都有扩展名,您可以使用
var regexAll = /[^\]*\.(\w+)$/;
Then you can do
然后你可以做
var total = path.match(regexAll);
var filename = total[0];
var extension = total[1];
回答by shift66
/^.*\/(.*)\.?(.*)$/g
after this first group is your file name and second group is extention.
/^.*\/(.*)\.?(.*)$/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
This works even if your filename contains more then one dotes or doesn't contain dots at all (has no extention).
EDIT:
This is for linux, for windows use this /^.*\\(.*)\.?(.*)$/g
(in linux directory separator is /
in windows is \
)
即使您的文件名包含多个点或根本不包含点(没有扩展名),这也有效。
编辑:
这是针对 linux,对于 windows 使用这个/^.*\\(.*)\.?(.*)$/g
(在 linux 目录分隔符是/
在 windows 中\
)
回答by fivedigit
You can use groups in your regular expression for this:
为此,您可以在正则表达式中使用组:
var regex = /^([^\]*)\.(\w+)$/;
var matches = filename.match(regex);
if (matches) {
var filename = matches[1];
var extension = matches[2];
}
回答by Alex Ander
This will recognize even /home/someUser/.aaa/.bb.c
:
这甚至会识别/home/someUser/.aaa/.bb.c
:
function splitPathFileExtension(path){
var parsed = path.match(/^(.*\/)(.*)\.(.*)$/);
return [parsed[1], parsed[2], parsed[3]];
}
回答by Mark Smith
I know this is an old question, but here's another solution that can handle multiple dots in the name and also when there's no extension at all (or an extension of just '.'):/^(.*?)(\.[^.]*)?$/
我知道这是一个老问题,但这里有另一种解决方案,它可以处理名称中的多个点,也可以在根本没有扩展名(或只有 '.' 的扩展名)时处理:/^(.*?)(\.[^.]*)?$/
Taking it a piece at a time:^
Anchor to the start of the string (to avoid partial matches)
一次取一块:^
锚定到字符串的开头(以避免部分匹配)
(.*?)
Match any character .
, 0 or more times *
, lazily ?
(don't just grab them all if the later optional extension can match), and put them in the first capture group (
)
.
(.*?)
匹配任何字符.
,0 次或多次*
,懒惰地?
(如果后面的可选扩展名可以匹配,不要只抓取它们),并将它们放在第一个捕获组中(
)
。
(\.
Start a 2nd capture group for the extension using (
. This group starts with the literal .
character (which we escape with \
so that .
isn't interpreted as "match any character").
(\.
使用 为扩展启动第二个捕获组(
。该组以文字.
字符开头(我们使用它进行转义,\
因此不会.
被解释为“匹配任何字符”)。
[^.]*
Define a character set []
. Match characters notin the set by specifying this is an inverted character set ^
. Match 0 or more non-.
chars to get the rest of the file extension *
. We specify it this way so that it doesn't match early on filenames like foo.bar.baz
, incorrectly giving an extension with more than one dot in it of .bar.baz
instead of just .baz
.
.
doesn't need escaped inside []
, since everything (except^
) is a literal in a character set.
[^.]*
定义一个字符集[]
。通过指定这是一个反转字符集来匹配不在集合中的字符^
。匹配 0 个或多个非.
字符以获取文件扩展名的其余部分*
。我们以这种方式指定它,这样它就不会在早期匹配文件名,例如foo.bar.baz
,错误地给出一个包含多个点的扩展名.bar.baz
而不是.baz
.
.
不需要在里面转义[]
,因为所有内容(除了^
)都是字符集中的文字。
)?
End the 2nd capture group )
and indicate that the whole group is optional ?
, since it may not have an extension.
)?
结束第二个捕获组)
并指出整个组是可选的?
,因为它可能没有扩展名。
$
Anchor to the end of the string (again, to avoid partial matches)
$
锚定到字符串的末尾(再次,避免部分匹配)
If you're using ES6 you can even use destructing to grab the results in 1 line:[,filename, extension] = /^(.*?)(\.[^.]*)?$/.exec('foo.bar.baz');
which gives the filename as 'foo.bar'
and the extension as '.baz'
.'foo'
gives 'foo' and ''
'foo.'
gives 'foo'
and '.'
'.js'
gives ''
and '.js'
如果您使用的是 ES6,您甚至可以使用析构来获取 1 行中的结果:[,filename, extension] = /^(.*?)(\.[^.]*)?$/.exec('foo.bar.baz');
它给出了文件名 as'foo.bar'
和扩展名 as '.baz'
。'foo'
给予'foo' and ''
'foo.'
给予'foo'
和'.'
'.js'
给予''
和'.js'
回答by gabo bernal
I think this is a better approach as matches only valid directory, file names and extension. and also groups the path, filename and file extension. And also works with empty paths only filename.
我认为这是一个更好的方法,因为只匹配有效的目录、文件名和扩展名。并对路径、文件名和文件扩展名进行分组。并且也仅适用于空路径文件名。
^([\w\/]*?)([\w\.]*)\.(\w)$
Test cases
测试用例
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
Output
输出
[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]