【问题标题】:Javascript regex for matching/extracting file extension用于匹配/提取文件扩展名的 Javascript 正则表达式
【发布时间】:2011-07-05 11:50:18
【问题描述】:

下面的正则表达式

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

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

filename-jpg
filename#gif
filename.png

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

更新基于 tvanofsson 的 cmets,我想澄清一下,当 JS 函数接收到字符串时,该字符串将已经包含一个不带空格且不带点和其他特殊字符的文件名(它实际上将被处理为 @987654323 @)。问题不在于解析文件名,而在于错误地解析了 slug - 当它真正应该返回 null 或空字符串时,该函数返回“jpg”的扩展名,当它被赋予“filename-jpg”时,正是这种行为需要待修正。

【问题讨论】:

  • 正则表达式是否必须确定文件名是否为合法文件名?什么定义了合法的文件名?什么定义了合法的文件扩展名?例如,foo bar.zi_ 是合法的文件名吗? foo.bar.zi_ 怎么样?
  • 典型的操作系统文件名..在我们的系统中不会发生带有空格的示例,@stema 提供的答案似乎适用于双扩展名,所以对我来说已经足够了。
  • 这两个例子都是 Unix 和 Windows 中的合法文件名。您可以通过详细说明您认为是合法文件名的内容来改进您的问题。它会给出答案,尤其是。接受的答案对可能希望解决相同或类似问题的未来读者更有意义。

标签: javascript regex


【解决方案1】:

只需在正则表达式中添加.

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

因为点是正则表达式中的特殊字符,您需要对其进行转义以匹配它:\.

您的模式现在将匹配任何以点结尾且后跟至少一个来自[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 个字符。

【讨论】:

  • 如果我不需要匹配中的点而只需要扩展名怎么办?
  • @user2727195 没有点,您不匹配扩展名。如果你的意思是......你如何只使用结果文本,那么你可以使用子字符串,如下所示:( ("file.ext").match(patt1) || '').substring(1);
  • .tar.gz 扩展也失败
  • 上面评论中的代码对我不起作用。如果您只想要扩展名,而不是点,请... const ext = ("file.ext".match(/\.[0-9a-z]{1,5}$/i) || [""])[0].substring(1)
【解决方案2】:

试试

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

此正则表达式对于从 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 @stema 谁offers pretty good advice 涉及一些 RegExp 语法基础知识。

【讨论】:

    【解决方案3】:

    示例列表:

    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.

    【讨论】:

      【解决方案4】:

      ONELINER:

      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)}`))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-05
        • 2013-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多