regex 用于匹配/提取文件扩展名的Javascript正则表达式

fquxozlt  于 2023-03-13  发布在  Java
关注(0)|答案(6)|浏览(192)

下面的正则表达式

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

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

filename-jpg
filename#gif
filename.png

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

  • UPDATE基于tvanofsson的注解,我想澄清一下,当JS函数接收到字符串时,该字符串将已经包含一个没有空格、没有点和其他特殊字符的文件名(实际上是slug处理的)问题不在于解析文件名,而在于错误地解析了slugs --函数在给定“filename-jpg”时返回扩展名“jpg”当它实际上应该返回null或空字符串时,需要纠正这种行为。*
qvsjd97n

qvsjd97n1#

只需向正则表达式中添加一个.

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

因为点在regex中是一个特殊字符,所以需要对其进行转义以匹配其字面含义:\. .
现在,您的模式将匹配[0-9a-z]中以点结尾且后跟至少一个字符的任何字符串。

示例:

[
  "foobar.a",
  "foobar.txt",
  "foobar.foobar1234"
].forEach( t => 
  console.log(
    t.match(/\.[0-9a-z]+$/i)[0]
  ) 
)

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

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

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

piwo6bdm

piwo6bdm2#

试试看

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

这个RegExp对于从URL中提取文件扩展名非常有用-即使是那些具有?foo=1查询字符串和#hash结尾的URL。
它还将为您提供扩展名$1

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"]

P.S.+1 for @stema,他就所涉及的一些RegExp语法基础提供了很好的建议。

jdgnovmf

jdgnovmf3#

示例列表:

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

Test page .

vfh0ocws

vfh0ocws4#

一行:

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

上述解决方案包括链接。它采用最后一个点和第一个“?“或“#“字符或字符串结尾之间的所有内容。要忽略“?“和“#“字符,请使用/\.([^.]*)$/。要仅忽略“#“,请使用/\.([^.]*?)(?=\?|$)/。示例

function getExtension(filename) {
  return (filename.match(/\.([^.]*?)(?=\?|#|$)/) || [])[1];
}

// TEST
[
  "abcd.Ef1",
  "abcd.efg",
  "abcd.efg?aaa&a?a=b#cb",
  "abcd.efg#aaa__aa?bb",
  "abcd",
  "abcdefg?aaa&aa=bb",
  "abcdefg#aaa__bb",
].forEach(t=> console.log(`${t.padEnd(21,' ')} -> ${getExtension(t)}`))
4xy9mtcn

4xy9mtcn5#

我在O'Reilly Regular Expressions Cookbook上找到了这个解决方案(第8章,第24节),它不区分大小写,可以与.NET,Java,JavaScript,PCRE,Perl,Python和Ruby一起使用。

\.[^.\\/:*?"<>|\r\n]+$

文件扩展名必须以点开始,因此,我们在正则表达式的开头加上了。
像Version 2.0.txt这样的文件名可能包含多个点。最后一个点是文件名和扩展名之间的分界点。扩展名本身不应该包含任何点。我们在正则表达式中通过在字符类中放置一个点来指定这一点。点只是字符类中的一个文字字符。所以我们不需要转义它,正则表达式末尾的锚确保我们匹配的是.txt而不是.0。
如果字符串以反斜杠结尾,或者文件名不包含任何点,则正则表达式根本不匹配;当匹配时,它将匹配扩展名,包括分隔扩展名的点和...

laik7k3q

laik7k3q6#

我建议使用这个函数,因为它可以避免返回null

const getExtension = (filename?: string): string | undefined => {
  if (!filename) return undefined
  const match = /\.([^.]+)$/.exec(filename)
  return match ? match[1] : undefined
}

此函数接受一个可选的filename参数,该参数可以是未定义的。如果未定义文件名,则函数返回undefined。否则,函数使用正则表达式从文件名中提取文件扩展名。如果正则表达式匹配,则函数返回提取的文件扩展名;否则返回undefined。

const getExtension = (filename) => {
  if (!filename) return undefined
  const match = /\.([^.]+)$/.exec(filename)
  return match ? match[1] : undefined
}

[
  "a.abc.x.ico",
  "foobar.a",
  "foobar.txt",
  "foobar.foobar1234",
  "undegined",
  undefined, null
].forEach(t =>
  console.log(
    getExtension(t)
  )
)

相关问题