【问题标题】:Regex for extracting filename from path用于从路径中提取文件名的正则表达式
【发布时间】:2012-03-10 21:54:07
【问题描述】:

我只需要从以下路径中提取文件名(无文件扩展名)......

\\my-local-server\path\to\this_file may_contain-any&character.pdf

我已经尝试了几件事,大部分都基于 http://regexr.com?302m5 之类的东西,但无法完全实现

【问题讨论】:

  • 哪种语言?某些语言在其标准库中具有解析 URI 的方法。
  • 我怀疑正则表达式会比获取最后一个路径分隔符的索引更快,但我可能是错的。
  • 这个问题很模糊,因为它只包含一个路径和文件名结构的例子。正则表达式用于匹配和/或捕获具有一定相似性的不同结构。

标签: regex


【解决方案1】:

试试this:

[^\\]+(?=\.pdf$)

它匹配除反斜杠之外的所有内容,字符串末尾紧跟.pdf

你也可以(也许更好)像这样将你想要的部分加入捕获组:

([^\\]+)\.pdf$

但是您如何指代这个组(括号中的部分)取决于您使用的语言或正则表达式风格。在大多数情况下,它会像 $1\1 一样,或者库将提供一些方法来在正则表达式匹配后通过其编号获取捕获组。

【讨论】:

  • 应该更像:[^\\](.+)\.pdf$
  • @macduff 问题也是路径还是文件名..?
  • 我理解它是文件名,而不是扩展名或路径,如果我误解了,请见谅。
  • @KL-7 谢谢,但我不想要 .pdf。我尝试使用[^\\]+[^.pdf]$,但这个概念不起作用
  • 如果扩展名必须是 .pdf. 并且路径是 variable,这是一个很好的答案。它匹配带有点的路径和没有路径的文件。不过,我认为明确指定路径可能会更好。
【解决方案2】:

这将获得文件名,但也会获得点。您可能希望截断代码中的最后一位数字。

[\w-]+\.

更新

@Geoman 如果文件名中有空格,则使用下面的修改模式

[ \w-]+\.      (space added in brackets)

Demo

【讨论】:

  • 失败:c:\fakepath\some filename with spaces.png
  • 如果路径包含带有点的文件夹名称,则失败。
  • 要求是不带扩展名的文件名。您可以根据需要发布单独的问题
  • 这适用于我的相关问题(带扩展名的文件名,但没有目录——只需在\. 之后添加[\w-]*$——这也消除了文件夹中有一个点的问题名称)。
  • 如果文件名没有扩展名也会失败。
【解决方案3】:
^\\(.+\\)*(.+)\.(.+)$

这个正则表达式已经在这两个例子上进行了测试:

\var\www\www.example.com\index.php
\index.php

第一个块“(.+\)*”匹配目录路径。
第二个块“(.+)”匹配没有扩展名的文件名。
第三块“(.+)$”匹配扩展名。

【讨论】:

  • 这是一种存在一些问题的通用方法。这在没有扩展名的文件名上失败,这在 *NIX 系统上并不少见。此外,问题表明双前导反斜杠,所以我可能会在捕获组之外添加另一个转义反斜杠。没有提到捕获路径或扩展名,因此可以简化。
  • 如果文件没有路径也会失败。
【解决方案4】:

如果有人正在寻找文件的 javascript 中的 windows 绝对路径(和相对路径)javascript 正则表达式:

var path = "c:\\my-long\\path_directory\\file.html";


((/(\w?\:?\\?[\w\-_\\]*\\+)([\w-_]+)(\.[\w-_]+)/gi).exec(path);

输出是:

[
"c:\my-long\path_directory\file.html", 
"c:\my-long\path_directory\", 
"file", 
".html"
]

【讨论】:

    【解决方案5】:

    以下是对 Angelo 出色答案的轻微修改,允许在路径、文件名和扩展名中使用空格以及缺少的部分:

    function parsePath (path) {
        var parts = (/(\w?\:?\\?[\w\-_ \\]*\\+)?([\w-_ ]+)?(\.[\w-_ ]+)?/gi).exec(path);
        return {
            path: parts[0] || "",
            folder: parts[1] || "",
            name: parts[2] || "",
            extension: parts[3] || "",
        };
    }
    

    【讨论】:

      【解决方案6】:

      这是一个适用于 windows/unix 的替代方案:

      "^(([A-Z]:)?[\.]?[\\{1,2}/]?.*[\\{1,2}/])*(.+)\.(.+)"

      第一个块:路径
      第二块:虚拟
      第三块:文件名
      第四块:扩展

      测试日期:

      ".\var\www\www.example.com\index.php"
      "\var\www\www.example.com\index.php"
      "/var/www/www.example.com/index.php"
      "./var/www/www.example.com/index.php"
      "C:/var/www/www.example.com/index.php"
      "D:/var/www/www.example.com/index.php"
      "D:\\var\\www\\www.example.com\\index.php"
      "\index.php"
      "./index.php"
      

      【讨论】:

        【解决方案7】:

        这只是@hmd 的一个细微变化,因此您不必截断.

        [ \w-]+?(?=\.)
        

        Demo

        真的,感谢@hmd。我只是稍微改进了一下。

        【讨论】:

        • 如果路径包含点或文件名没有扩展名或没有路径,则失败。
        【解决方案8】:

        此正则表达式提取文件扩展名,如果第 3 组不为空,则为扩展名。

        .*\\(.*\.(.+)|.*$)
        

        【讨论】:

          【解决方案9】:

          还有一个用于 dir 和 root 中的文件

             ^(.*\\)?(.*)(\..*)$
          

          目录中的文件

          Full match  0-17    `\path\to\file.ext`
          Group 1.    0-9 `\path\to\`
          Group 2.    9-13    `file`
          Group 3.    13-17   `.ext`
          

          根目录下的文件

          Full match  0-8 `file.ext`
          Group 2.    0-4 `file`
          Group 3.    4-8 `.ext`
          

          【讨论】:

            【解决方案10】:

            对于大多数情况(即一些 win 、 unx 路径、分隔符、裸文件名、点、文件扩展名),以下一个就足够了:

             // grap the dir part (1), the dir sep(2) , the bare file name (3) 
             path.replaceAll("""^(.*)[\\|\/](.*)([.]{1}.*)""","$3")
            

            【讨论】:

              【解决方案11】:

              点击TEST显示的这些链接上的解释按钮,看看它们是如何工作的。


              这是特定于 pdf 扩展的。

              TEST^.+\\([^.]+)\.pdf$


              这是特定于任何扩展的,而不仅仅是pdf

              TEST^.+\\([^.]+)\.[^\.]+$


              ([^.]+) 这是$1 捕获组,用于提取文件名不带扩展名


              \\my-local-server\path\to\this_file may_contain-any&character.pdf

              会回来

              this_file may_contain-any&character

              【讨论】:

              • 在包含多个点的文件名和没有扩展名的文件名上都失败。
              • 在没有路径的文件上。
              • 停止在所有 cmets 上拖钓。这回答了 OP 的问题。
              • 你是对的。如果我冒犯了你或其他任何人,我很抱歉。这里的许多答案都解决了 OPs 问题。我的问题实际上是问题而不是答案。根据问题,大多数答案可能是正确的,这是模糊的。我是新人,我应该采取不同的行动。对不起!
              【解决方案12】:

              我正在使用此正则表达式将文件的文件名替换为index。它匹配不包含斜杠的连续字符串,后跟. 和字符串末尾的单词字符串。它将检索包含空格和点的文件名,但会忽略完整的文件扩展名。

              const regex = /[^\\/]+?(?=\.\w+$)/
              
              console.log('/path/to/file.png'.match(regex))
              console.log('/path/to/video.webm'.match(regex))
              console.log('/path/to/weird.file.gif'.match(regex))
              console.log('/path with/spaces/and file.with.spaces'.match(regex))

              【讨论】:

                【解决方案13】:

                TEST^(.*[\\\/])?(.*?)(\.[^.]*?|)$

                示例:

                /^(.*[\\\/])?(.*?)(\.[^.]*?|)$/.exec("C:\\folder1\\folder2\\foo.ext1.ext")
                

                结果:

                0: "C:\folder1\folder2\foo.ext1.ext"
                1: "C:\folder1\folder2\"
                2: "foo.ext1"
                3: ".ext"
                

                $1 捕获组是文件夹
                $2 捕获组是不带扩展名的名称
                $3 捕获组是扩展名(仅最后一个)

                适用于:

                • C:\folder1\folder2\foo.ext
                • C:\folder1\folder2\foo.ext1.ext
                • C:\folder1\folder2\name-without extension
                • only name
                • name.ext
                • C:\folder1\folder2\foo.ext
                • /folder1/folder2/foo.ext
                • C:\folder1\folder2\foo
                • C:\folder1\folder2\
                • C:\special&chars\folder2\f [oo].ext1.e-x-t

                【讨论】:

                  【解决方案14】:

                  直接方法:

                  为了回答您所写的问题,这将提供最精确的匹配:

                  ^\\\\my-local-server\\path\\to\\(.+)\.pdf$
                  

                  一般方法:

                  这个正则表达式简短而简单,可以匹配 Windows 和 *NIX 上任何文件夹(带或不带扩展名)中的任何文件名:

                  .*[\\/]([^.]+)
                  

                  如果一个文件的名称中有多个点,上面的正则表达式将捕获文件名直到第一个点。如果您知道您不会有没有扩展名的文件或者您不会有包含点的路径,则可以轻松地修改它以匹配到最后一个点。

                  如果您知道该文件夹将只包含 .pdf 文件,或者您只对 .pdf 文件感兴趣并且知道扩展名永远不会拼写错误,我会使用这个正则表达式:

                  .*[\\/](.+)\.pdf$
                  

                  说明:

                  • . 匹配除行终止符之外的任何内容。
                  • *重复上一次匹配到尽可能多的次数。
                  • [\\/] 匹配最后一个反斜杠或正斜杠(之前的反斜杠由 .* 使用)。如果您知道只会使用一种类型的环境,则可以省略反斜杠或正斜杠。 如果要捕获路径,请将.*.*[\\/] 括在括号中。
                  • 括号将捕获其中匹配的内容。
                  • [^.] 匹配任何不是文字点的内容。
                  • + 尽可能多地重复上一场比赛一次或多次。
                  • \. 匹配文字点。
                  • pdf 匹配字符串 pdf。
                  • $ 断言字符串的结尾。

                  如果您想匹配名称中包含零个、一个或多个点的文件,这些点放置在一个变量路径中,该路径也可能包含点,它将开始变得丑陋。我没有为这种情况提供答案,因为我认为这不太可能。

                  编辑:如果还要捕获没有路径的文件名,请将第一部分替换为 (?:.*[\\/])?,这是一个可选的非捕获组。

                  【讨论】:

                    【解决方案15】:

                    这行得通吗...

                    .*\/(.+)$
                    

                    在这里发帖让我得到反馈

                    【讨论】:

                      【解决方案16】:

                      我使用@"[^\\]+$" 这给出了包含扩展名的文件名。

                      【讨论】:

                      • 我不敢相信这是 3 小时前回答的,非常感谢!我不得不从 S3 资源路径中提取没有扩展名的文件名,因此最后没有点。只需将 \\ 替换为 \/ 即可使用 S3 路径,就像一个魅力!
                      【解决方案17】:

                      这里有一个解决方案来提取不带扩展名的文件名。 我从@Hammad Khan 的答案开始,并在搜索字符中添加点。所以,点可以是文件名的一部分:

                      [ \w-.]+\.
                      

                      然后使用正则表达式look ahead(?= )作为一个点,所以它会在最后一个点(扩展名之前的点)停止搜索,并且该点不会出现在结果中:

                      [ \w-.]+(?=[.])
                      

                      重新排序,没必要但更好看:

                      [\w-. ]+(?=[.])
                      

                      【讨论】:

                        【解决方案18】:

                        回答:

                        • 文件名和目录空间支持
                        • 命名的捕获组
                        • 获取无限的文件扩展名(捕获file.tar.gz,而不仅仅是file.tar
                        • *NIX 和 Win 支持

                        ^.+(\\|\/)(?<file_name>([^\\\/\n]+)(\.)?[^\n\.]+)$

                        解释:

                        1. ^.+(\\|\/) 获取文件路径中直到最终 /\ 的任何内容
                        2. (?<file_name> 开始命名捕获组
                        3. ([^\\\/\n]+) 获取除换行符或新文件之外的任何内容
                        4. (\.)?[^\n\.]+ 不是很需要,但它可以很好地解决文件名中出现奇数字符的问题
                        5. )$结束命名的捕获组和结束行

                        请注意,如果您将其放入字符串中并且需要转义反斜杠(例如使用 C),您将使用此字符串:

                        "^.+(\\\\|\/)(?<file_name>([^\\\/\n]+)(\.)?[^\n\.]+)$"

                        【讨论】:

                          【解决方案19】:

                          如果要返回带有扩展名的文件名,Regex 应该如下:

                          [A-Za-z0-9_\-\.]+\.[A-Za-z0-9]+$

                          适用于

                          path/to/your/filename.some
                          path/to/your/filename.some.other
                          path\to\your\filename.some
                          path\to\your\filename.some.other
                          http://path/to/your/filename.some
                          http://path/to/your/filename.some.other
                          And so on
                          

                          返回带有扩展名的完整文件名(例如:filename.some 或 filename.some.other)


                          如果你想返回没有最后扩展名的文件名 Regex 应该如下:

                          [A-Za-z0-9_\-\.]+(?=\.[A-Za-z0-9]+$)
                          

                          返回没有最后扩展名的完整文件名(例如:“filename.some”的“filename”和“filename.some.other”的“filename.some”)

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 2021-06-05
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2018-12-07
                            相关资源
                            最近更新 更多