我想从一个路径中删除所有目录名:
Payload/brownie.app/Info.plist
应该变成什么?
Info.plist
我应该使用什么正则表达式,还是可以在Java中使用String的replace()方法? 谢谢!
尝试使用这个:
new File("Payload/brownie.app/Info.plist").getName()
此函数返回文件名,不包括目录路径。
示例:
String filename = new File("Payload/brownie.app/Info.plist").getName();
System.out.println(filename);
输出:
Info.plist
不需要使用正则表达式,只需查找最后一个斜杠并使用子字符串:
int index = path.lastIndexOf(File.separatorChar);
String name = path.substring(index+1);
或者使用:
new File(path).getName();
public static String extractFilename(String path) {
java.util.regex.Pattern p = java.util.regex.Pattern.compile('^[/\\\\]?(?:.+[/\\\\]+?)?(.+?)[/\\\\]?$');
java.util.regex.Matcher matcher = p.matcher(path);
if ( matcher.find() ) {
return matcher.group(1);
}
return null;
}
使用中:
println extractFilename("data\\\\path/to/file/RandomFile.pdf")
println extractFilename("RandomFile.pdf")
println extractFilename("RandomFile.pdf/")
println extractFilename("data\\\\path/to/file/RandomFile.pdf/")
println extractFilename("/data\\\\path/to/file/RandomFile.pdf/")
println extractFilename("/data\\\\path/to/file/RandomFile.pdf")
println extractFilename("/RandomFile.pdf")
println extractFilename("/RandomFile.pdf/")
println extractFilename("/")
打印
RandomFile.pdf
RandomFile.pdf
RandomFile.pdf
RandomFile.pdf
RandomFile.pdf
RandomFile.pdf
RandomFile.pdf
RandomFile.pdf
/
为Uday解释一下。实际上这是一个相当复杂的问题,我不确定今天是否能对所有内容进行论证,但我会尽力 :)
^[/\\\\]?(?:.+[/\\\\]+?)?(.+?)[/\\\\]?$
0: 整个正则表达式
^
1: 开始于
[/\\\\]?
2:斜杠或反斜杠(是的,一个需要四个斜杠,太疯狂了!)。可以出现一次或不出现,因此不是必需的。
(?:.+[/\\\\]+?)?
第三步是比较复杂的。它旨在跳过除了与这个确切模式匹配的最后一个之外的其他所有内容,这是一个非捕获组 (?:... 我们正在寻找多次出现的任何字符,后面跟着一个斜线。
该组可以重复多次,但它是非贪婪的。因此,它是在说做这个,除非你匹配以下在 4 中解释的正则表达式。
但是,由于括号外面有问号,因此并不需要整个片段。例如,"/RandomFile.pdf/" 将不会在此处生成匹配项,并继续进行步骤 4。
然而,我现在发现这有点奇怪,因为 .+ 是贪婪的,但它仍然在寻找斜线进行匹配。可能是组的特性使其非贪婪,或者是 Java 模式语法中的一个错误。
(.+?)[/\\\\]?$
4: 由于正则表达式适用于整个字符串,因此它也必须一直匹配到末尾。之前在第3次匹配中使用了非贪婪的+?,这意味着只有当其后面的正则表达式未匹配时,它才会匹配。我们的单词在$处,在括号内,该括号可能以斜杠结尾,也可能不是。如果没有文件名,只有斜杠,则我选择返回根路径作为文件名,因为它也是一个文件名(目录名)。
5: 括号是一个捕获组,这就是我们最终返回的内容。
希望这能更好地解释清楚。
String name = directory.replaceAll(".*/","")
,就这么简单。如果你要处理一个由浏览器传递给Web服务器的文件路径,你无法确定它是DOS风格的路径、Unix风格的路径还是只是没有路径的文件名。如果你真的需要一个正则表达式,这应该可以解决:
String path = "Payload/brownie.app/Info.plist";
String filename = path.replaceFirst("(^.*[/\\\\])?([^/\\\\]*)$","$2");
这将适用于DOS、Unix或不存在的路径。
不过,如dogbane建议所示,使用子字符串会更易读,但如果您正在处理多平台输入,则需要添加逻辑来检查两种类型的文件分隔符。
之前的答案都比使用完整的正则表达式简单。但是如果你真的想使用一个,这里是一个你可以使用的正则表达式模式:".*/(.+)"
Pattern p = Pattern.compile(".*/(.+)");
Matcher matcher = p.matcher("Payload/brownie.app/Info.plist");
if ( matcher.find() ) {
System.out.println("result: "+matcher.group(1));
}
从其他答案中可以看出,这比严格需要的代码更多,但如果您正在进行更复杂的模式匹配和字符串提取,则正则表达式是一个不错的选择。
File.getName()
去除路径时要小心,如果你正在处理的路径可能来自另一个操作系统(比如Linux服务器解析上传文件的DOS路径),会出现问题。File.getName()
只会去除操作系统认为是目录的部分。在Linux上,“C:\somedir\myfile.txt”是一个完全有效的文件名。 - codelahoma