【问题标题】:javascript regex for extracting filename from Content-Disposition header用于从 Content-Disposition 标头中提取文件名的 javascript 正则表达式
【发布时间】:2014-05-28 01:57:10
【问题描述】:

Content-disposition 标头包含可以轻松提取的文件名,但有时它包含双引号,有时不包含引号,并且可能还有其他一些变体。有人可以编写一个适用于所有情况的正则表达式吗?

Content-Disposition: attachment; filename=content.txt

以下是一些可能的目标字符串:

attachment; filename=content.txt
attachment; filename*=UTF-8''filename.txt
attachment; filename="EURO rates"; filename*=utf-8''%e2%82%ac%20rates
attachment; filename="omáèka.jpg"
and some other combinations might also be there

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

    我创建了一个正则表达式,使用filename 组查找这些名称

    /(?<=filename(?:=|\*=(?:[\w\-]+'')))["']?(?<filename>[^"';\n]+)["']?/g
    

    const regex = /(?<=filename(?:=|\*=(?:[\w\-]+'')))["']?(?<filename>[^"';\n]+)["']?/g
    
    const filenames = `
    attachment; filename=content.txt
    attachment; filename*=UTF-8''filename.txt
    attachment; filename="EURO rates"; filename*=utf-8''%e2%82%ac%20rates
    attachment; filename="omáèka.jpg"
    `
    
    function logMatches(){
      const array = new Array
    
      filenames.split("\n").forEach(line => {
        if(!line.trim()) return
    
        const matches = line.matchAll(regex)
        const groups = Array.from(matches).map(match => match?.groups?.filename)
    
        array.push(groups.length === 1 ? groups[0] : groups)
      })
    
      console.log(array)
    }
    
    logMatches()

    【讨论】:

      【解决方案2】:
      filename[^;\n]*=(UTF-\d['"]*)?((['"]).*?[.]$\2|[^;\n]*)?
      

      我已经升级了 Robin 的解决方案来做两件事:

      1. 捕获文件名,即使它已转义双引号。

      2. 将 UTF-8'' 部分捕获为单独的组。

      这是一个 ECMAScript 解决方案。

      https://regex101.com/r/7Csdp4/3/

      【讨论】:

      • 我已经调整了您的正则表达式,允许在 = 之后和名称之前使用空格:filename[^;\n]*=\s*(UTF-\d['"]*)?((['"]).*?[.]$\2|[^;\n]*)?
      【解决方案3】:
      /filename[^;=\n]*=(?:(\\?['"])(.*?)\1|(?:[^\s]+'.*?')?([^;\n]*))/i
      

      https://regex101.com/r/hJ7tS6/51

      编辑:你也可以使用这个解析器: https://github.com/Rob--W/open-in-browser/blob/master/extension/content-disposition.js

      【讨论】:

        【解决方案4】:

        稍作修改以匹配我的用例(去掉所有引号和 UTF 标签)

        filename\*?=['"]?(?:UTF-\d['"]*)?([^;\r\n"']*)['"]?;?

        https://regex101.com/r/UhCzyI/3

        【讨论】:

        • 如果文件名包含 ' 则失败
        【解决方案5】:

        这是我的正则表达式。它适用于 Javascript。

        filename\*?=((['"])[\s\S]*?\2|[^;\n]*)
        

        我在我的项目中使用了这个。

        【讨论】:

          【解决方案6】:

          免责声明:以下答案仅适用于 PCRE(例如 Python / PHP),如果您必须使用 javascript,请使用 Robin 的答案。


          Robin 正则表达式的修改版本去掉了引号:

          filename[^;\n=]*=(['\"])*(.*)(?(1)\1|)
          
          filename        # match filename, followed by
          [^;=\n]*        # anything but a ;, a = or a newline
          =
          (['"])*         # either single or double quote, put it in capturing group 1
          (?:utf-8\'\')?  # removes the utf-8 part from the match
          (.*)            # second capturing group, will contain the filename
          (?(1)\1|)       # if clause: if first capturing group is not empty,
                          # match it again (the quotes), else match nothing
          

          https://regex101.com/r/hJ7tS6/28

          文件名在第二个捕获组中。

          【讨论】:

          • 这需要 PCRE 风格的正则表达式——OP 要求使用 JS。
          • @miqid 是的,很抱歉我编辑了我的答案。虽然我使用的是 python,所以我认为我的版本可以看作是我们这些不使用 javascript 的问题的通用解决方案。
          • res = re.search(r"filename[^;\n=]*=(['\"])*(.*)(?(1)\1|)", 字符串) res.group(2)
          【解决方案7】:

          您可以本着这种精神尝试一下:

          filename[^;=\n]*=((['"]).*?\2|[^;\n]*)
          
          filename      # match filename, followed by
          [^;=\n]*      # anything but a ;, a = or a newline
          =
          (             # first capturing group
              (['"])    # either single or double quote, put it in capturing group 2
              .*?       # anything up until the first...
              \2        # matching quote (single if we found single, double if we find double)
          |             # OR
              [^;\n]*   # anything but a ; or a newline
          )
          

          您的文件名在第一个捕获组中:http://regex101.com/r/hJ7tS6

          【讨论】:

          • 匹配的字符串不能包含双引号和“utf-8”
          • @adnankamili:最简单的解决方案可能是在之后执行此检查,与正则表达式分开。
          • /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(contentDisposition)[1]
          • 文件名[^;=\n]*=(?:(\\?['"])(.*?)\1|(?:[^\s]+'.* ?')?([^;\n]*))
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-04
          • 2011-12-23
          • 2022-07-06
          • 2015-05-12
          • 2012-03-10
          • 1970-01-01
          相关资源
          最近更新 更多