从路径中提取文件名的正则表达式

43
我需要从以下路径中提取文件名(没有文件扩展名)...
\\my-local-server\path\to\this_file may_contain-any&character.pdf
我已经尝试过几种方法,大多基于http://regexr.com?302m5之类的东西,但还无法成功。

3
哪种语言?有些语言在其标准库中有解析URI的方法。 - Felix Kling
2
我对正则表达式比获取最后一个路径分隔符的索引更快持怀疑态度,但我可能是错的。 - Dave Newton
这个问题含糊不清,因为它只包含了一种路径和文件名结构的示例。正则表达式用于匹配和/或捕获不同但有些相似的结构。 - Pan
20个回答

40
^\\(.+\\)*(.+)\.(.+)$

这个正则表达式在以下两个示例上进行了测试:

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

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


1
这是一种通用方法,但存在一些问题。在 *NIX 系统上,没有扩展名的文件名并不少见,因此此方法会失败。另外,问题中提到了双反斜杠,所以我可能会在捕获组之外添加另一个转义的反斜杠。问题中没有提到捕获路径或扩展名,因此可以简化处理。 - Pan
如果文件没有路径,也会失败。 - Pan

20

这段代码可以获取文件名,但也会获取点号。您可能需要在代码中将最后一位数截断。

[\w-]+\.

更新

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

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

演示


失败:c:\fakepath\some filename with spaces.png - xGeo
7
如果路径中包含名称带有点的文件夹,则会失败。 - MiroJanosik
要求是文件名不带扩展名。您可以针对您的需求发布一个单独的问题。 - TheTechGuy
2
这对我的相关问题起作用了(文件名带扩展名,但没有目录 -- 只需在 \. 后面添加 [\w-]*$ -- 这也解决了文件夹名称中有点的问题)。 - user241244
如果文件名没有扩展名,也会失败。 - Pan

16
这只是对 @hmd 的略微变化,这样您就不必截断 .
[ \w-]+?(?=\.)

演示

实际上,感谢@hmd。我只是稍微改进了它。


1
如果路径中包含点号,或者文件名没有扩展名,或者路径不存在,则操作失败。 - Pan

10
我使用@"[^\\]+$",这将返回包括文件扩展名在内的文件名。

1
我简直不敢相信这个问题已经在3小时前得到了解答,非常感谢!我需要从S3资源路径中提取没有扩展名和结尾没有点的文件名。只需要将\替换为/以适应S3路径,就可以完美解决了! - GSazheniuk
2
这正确吗?不应该是 [^\/]+$ 吗? - FabianoLothor
2
@fabianoLothor - 如果URL中有正斜杠,则按照您的方式处理。如果是反斜杠,则按照我的方式处理。问题是关于反斜杠的。 - user890332

9

试试这个

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

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

你也可以(也许这样更好)像这样将想要的部分提取到捕获组中:

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

但是,你如何引用括号内的组取决于你使用的语言或正则表达式。在大多数情况下,它将类似于$1\1,或者该库将提供一些方法来通过其匹配后的捕获组编号获取捕获组。


应该更像这样:[^\\](.+)\.pdf$ - macduff
@macduff 这个问题是关于路径还是仅仅文件名..? - noob
我理解它是文件名,但不包括扩展名或路径,如果我误解了,请原谅。 - macduff
@KL-7 谢谢,但我不想要这个 .pdf 文件。我尝试使用 [^\\]+[^.pdf]$,但这个概念没有起作用。 - Ben
[^\\^\/]+(?=\.ini$)将处理两种类型的斜杠。 - Vinit Siriah
显示剩余2条评论

4
我正在使用这个正则表达式来替换文件名为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))


3

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

示例:

/^(.*[\\\/])?(.*?)(\.[^.]*?|)$/.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

1
测试用例也很重要。 - Nor.Z
似乎相当强大。但是,如果文件名以前导的句点作为其名称的一部分,这个正则表达式将把整个名称视为没有名称的文件扩展名。存在这些类型的文件,比如.Rprofile.gitignore。我不确定它们应该被视为文件扩展名还是文件名,不过我倾向于后者。如果将第二个捕获组改为(\.?.*?),它似乎适用于您所有的测试案例。完整的正则表达式:^(.*[\\\/])?(\.?.*?)(\.[^.]*?|)$ - Therkel
额外的测试案例:C:\folder1\folder2\.没有扩展名的名称.只有前导点的名称 .名称.扩展名。此外,您的正则表达式已经正确处理了目录中的句点。请参见 C:\fol.d.er1\fo.lde.r2/.name- with extension.R - Therkel

3

如果有人正在寻找一个用于文件的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"
]

2
这是对安吉洛精彩回答的微小修改,它允许路径、文件名和扩展名中出现空格并且某些部分可能缺失:
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] || "",
    };
}

2

回答如下:

  • 文件名和目录空间支持
  • 命名捕获组
  • 可以获取无限的文件扩展名(可以捕获 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\.]+)$"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接