从路径中获取带或不带扩展名的文件名的正则表达式

3

在这段代码中,寻找一个正则表达式来提取出路径中除扩展名以外的文件名部分。

String filename = fullpath.replaceFirst(regex, "$1")

例如,以下是最简单的情况和我所做的内容:
- /path/filename.ext -> filename (fullpath.replaceFirst(".*/(.*)\\..*", "$1"))
这里有一些更高级的情况,我需要帮助解决:
- /filename.ext -> filename(可以以/开头) - filename. -> filename(可以以.结尾) - /filename -> filename(可能没有.) - filename.ext -> filename(可能没有/) - filename -> filename(可能没有.和/) - .filename -> .filename(可以以.开始) - /path/.filename -> .filename(可以紧接着/以.开始) - filename.part1.ext -> filename.part1(可以有中间的.) - /path_a/path.b/ ->(空字符串)(文件名可能不存在) - /path_a/path.b/filename -> filename(/之前的路径中可能有.)
编辑: 此处实际上没有任何文件,而fullpath不会导致任何文件。它来自URL请求。

7
new File(fullpath).getName() - XtremeBaumer
1
/path_a/path.b/ 是一个指向文件夹而非文件的有效路径。然而它仍然有一个名称。 - XtremeBaumer
new File(fullpath).getName()是Java中获取文件名的一种常见方式。它将给定的完整路径作为参数,并返回该路径所表示的文件或目录的名称。 - XtremeBaumer
@XtremeBaumer,你让我很困惑。我说过我尝试了你的代码,但它并没有给出正确的结果,为什么你还在推销它呢?new File("/path/filename.ext").getName()会返回"filename.ext"而不是我在问题中需要的"filename"。 - user1589188
可能是如何在Java中从字符串中删除文件扩展名?的重复问题。 - XtremeBaumer
显示剩余4条评论
3个回答

10
以下正则表达式将匹配所需部分:
^(?:.*\/)?([^\/]+?|)(?=(?:\.[^\/.]*)?$)

解释:

  • ^ 匹配行首
  • (?: 开始一个非捕获组
    • .*\/ 匹配到最后一个 / 字符
  • )? 非捕获组结束(可选)
  • ([^\/]+?|) 捕获任何非贪婪的字符,但不包括 / 或者什么也不匹配
  • (?= 开始一个正向前瞻
    • (?:\.[^\/.]*)? 匹配一个扩展名(可选)
    • $ 断言行尾
  • ) 正向前瞻结束

如果你处理的是多行输入字符串,需要更快速的正则表达式,请使用以下表达式(并打开 m 标志):

^(?:[^\/\r\n]*\/)*([^\/\r\n]+?|)(?=(?:\.[^\/\r\n.]*)?$)

点击此处查看实时演示

文件名将会被捕获并存储在第一个捕获组中。


2
@user1589188 是的,一个反斜杠需要两个。 - revo
是的,我已经这么做了。请帮我看看"/path/filename.ext".replaceFirst("^(?:.*\\/)?([^\\/]+?|)(?=(?:\\.[^\\/.]*)?$)", "$1")这段代码。它并没有打印出"filename"而是打印出了"filename.ext"。我错在哪里了? - user1589188
2
@user1589188 在这里不应该使用替换方法,但如果必须使用,您应该将正向先行断言更改为简单匹配集群:"/path/filename.ext".replaceFirst("^(?:.*\\/)?([^\\/]+?|)(?:\\.[^\\/.]*)?$", "$1") - revo
2
@user1589188 这个也可能会有帮助 https://regex101.com/r/9FUtDb/1/codegen?language=java - revo
3
非常印象深刻!@revo做得非常好!这很有效,并且你的解释非常完美,谢谢。 - Gosfly
显示剩余3条评论

3
您可以在File对象上使用getName()函数,然后使用正则表达式删除扩展名,并且您还可以检查它是否为文件:
File file = new File(fullpath);
if (file.isFile()) return file.getName().replace("\..*", "");
else return "";

1
谢谢,但我并不是在处理实际的文件。事实上,我正在处理一个请求URL,所以对于我来说没有文件需要检查。 - user1589188
没问题,感谢您的输入。如果其他人有文件需要处理,这应该会很有帮助。 - user1589188
@XtremeBaumer,如果路径在文件系统中不存在,isFile()检查是否能够正常工作? - SteapStepper69
如果文件实际上不存在,则isFile()isDirectory()都返回false - XtremeBaumer
但是,如果OP在磁盘上没有该文件,那么这种方法就行不通了。 - SteapStepper69

3
使用文件路径(String pathFile)获取带扩展名的文件名,然后使用FilenameUtils.removeExtension删除扩展名。
String nameDocument = pathFile.substring(pathFile.lastIndexOf("/") + 1);

String fileNameWithOutExt = FilenameUtils.removeExtension(nameDocument);

嘿,谢谢。我猜对于其他人来说这很有用。但在我的情况下,使用那个工具似乎不能得到“.filename”,因为路径是“/path/.filename”。 - user1589188

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