用于匹配/提取文件扩展名的javascript regex

Javascript regex for matching/extracting file extension

以下regex

1
var patt1=/[0-9a-z]+$/i;

提取字符串的文件扩展名,例如

1
2
3
filename-jpg
filename#gif
filename.png

当字符串实际上是一个以一个点作为分隔符的文件名时,如何修改这个正则表达式以只返回扩展名?(显然,文件名gif不是常规文件名)

更新基于Tvanofsson的评论,我想澄清的是,当JS函数接收到字符串时,该字符串将已经包含一个没有空格的文件名,没有圆点和其他特殊字符(它实际上将被处理为一个slug)。问题不在于解析文件名,而在于错误地解析slugs——当函数被赋予"filename jpg"时,它返回了"jpg"的扩展名,而实际上它应该返回null或空字符串,需要纠正这种行为。


只需在regex中添加一个EDOCX1[0]

1
var patt1=/\.[0-9a-z]+$/i;

因为点在regex中是一个特殊的字符,所以需要对它进行转义,以便与它进行字面匹配:\.

现在,您的模式将与任何以点结尾的字符串相匹配,该字符串后面至少有一个来自[0-9a-z]的字符。

例子:

1
2
3
4
5
6
7
8
9
[
 "foobar.a",
 "foobar.txt",
 "foobar.foobar1234"
].forEach( t =>
  console.log(
    t.match(/\.[0-9a-z]+$/i)[0]
  )
)

如果要将扩展限制为一定数量的字符,则需要替换+

1
var patt1=/\.[0-9a-z]{1,5}$/i;

将允许点后至少有1个字符,最多5个字符。


尝试

1
var patt1 = /\.([0-9a-z]+)(?:[\?#]|$)/i;

这个regexp对于从URL提取文件扩展名很有用,即使是那些有?foo=1查询字符串和#hash结尾的URL。

它还将为您提供扩展名为$1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var m1 = ("filename-jpg").match(patt1);
alert(m1);  // null

var m2 = ("filename#gif").match(patt1);
alert(m2);  // null

var m3 = ("filename.png").match(patt1);
alert(m3);  // [".png","png"]

var m4 = ("filename.txt?foo=1").match(patt1);
alert(m4);  // [".txt?","txt"]

var m5 = ("filename.html#hash").match(patt1);
alert(m5);  // [".html#","html"]

@stema的p.s.+1,他对涉及的一些regexp语法基础提供了非常好的建议。


示例列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var fileExtensionPattern = /\.([0-9a-z]+)(?=[?#])|(\.)(?:[\w]+)$/gmi
//regex flags -- Global, Multiline, Insensitive

var ma1 = 'css/global.css?v=1.2'.match(fileExtensionPattern)[0];
console.log(ma1);
// returns .css

var ma2 = 'index.html?a=param'.match(fileExtensionPattern)[0];
console.log(ma2);
// returns .html

var ma3 = 'default.aspx?'.match(fileExtensionPattern)[0];
console.log(ma3);
// returns .aspx

var ma4 = 'pages.jsp#firstTab'.match(fileExtensionPattern)[0];
console.log(ma4);
// returns .jsp

var ma5 = 'jquery.min.js'.match(fileExtensionPattern)[0];
console.log(ma5);
// returns .js

var ma6 = 'file.123'.match(fileExtensionPattern)[0];
console.log(ma6);
// returns .123

测试页。


ONELINER:

1
let ext = (filename.match(/\.([^.]*?)(?=\?|#|$)/) || [])[1]

上面的解决方案包括链接。egzamples(文件名->ext):

1
2
3
4
5
6
7
//"abcd.Ef1"               ->"Ef1"
//"abcd.efg"               ->"efg"
//"abcd.efg?aaa&a?a=b#cb"  ->"efg"
//"abcd.efg#aaa__aa?bb"    ->"efg"
//"abcd"                   -> undefined
//"abcdefg?aaa&aa=bb"      -> undefined
//"abcdefg#aaa__bb"        -> undefined

它需要最后一个点和第一个"EDOCX1"(7)或"EDOCX1"(8)字符或字符串结尾之间的所有内容。要忽略"EDOCX1"〔7〕和"EDOCX1"〔8〕字符,请使用/\.([^.]*)$/。要只忽略"#",请使用/\.([^.]*?)(?=\?|$)/