【问题标题】:Regex to strip all directorynames from Path (leave filename)正则表达式从路径中删除所有目录名(保留文件名)
【发布时间】:2011-01-29 18:45:59
【问题描述】:

我想从路径中删除所有目录名:

Payload/brownie.app/Info.plist

应该变成

Info.plist

我应该使用什么正则表达式,或者我可以在 java 中使用 String 中的 replace() 吗? 谢谢!

【问题讨论】:

    标签: java regex string


    【解决方案1】:

    试试这个:

    new File("Payload/brownie.app/Info.plist").getName()
    

    这将返回不带目录的文件名。

    例子:

    String filename = new File("Payload/brownie.app/Info.plist").getName();
    System.out.println(filename);
    

    输出:

    Info.plist
    

    【讨论】:

    • 不是正则表达式,而是最好的(面向对象,可读性)解决方案 IMO:+1
    • 我同意你的看法,@Carlos Heuberger ;)
    • 小心使用File.getName() 去除路径,如果您正在使用的路径可能来自另一个操作系统(例如解析上传文件的 DOS 路径的 Linux 网络服务器)。 File.getName() 只删除操作系统认为是目录的任何内容。 "C:\somedir\myfile.txt" 在 Linux 上是一个完全有效的文件名。
    【解决方案2】:

    您不需要正则表达式。只需找到最后一个斜杠并使用子字符串:

    int index = path.lastIndexOf(File.separatorChar);
    String name = path.substring(index+1);
    

    或使用:

    new File(path).getName();
    

    【讨论】:

    • 这个解决方案的问题是你可以有这样的网址:.../somepage.html?rurl=/x/y/z/something.html
    • 另外,请务必检查极端情况,例如文件位于根文件夹中或路径为空。 if (path == null) return null; int index = path.lastIndexOf(File.separatorChar);字符串名称 = path.substring(index+1);返回索引 == -1 ? null : path.substring(0, index);
    • 如果文件名以斜杠结尾则不起作用。如果文件名没有路径(相对文件)并且只是文件名,则将不起作用。不适用于目录名称,只是根目录的“斜线”。不适用于反斜杠,以及来自其他系统的混合斜杠路径( windows )。
    【解决方案3】:

    这涵盖了所有频谱目录、尾部或起始斜线。

    到目前为止,这里的所有其他人都没有...

    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
    /
    

    .................................................. ........................编辑......................... ..................................................... .

    对乌代的解释。这实际上是一个相当复杂的问题,我不确定我今天是否能证明所有这些,但我会试一试:)

    ^[/\\\\]?(?:.+[/\\\\]+?)?(.+?)[/\\\\]?$
    

    0:整个正则表达式

    ^
    

    1:以

    开头
    [/\\\\]?
    

    2:正斜杠或反斜杠(是的,四个斜杠为一个,疯了!)。一次或一次都没有,所以不需要。

    (?:.+[/\\\\]+?)? 
    

    3:这一步比较复杂。它旨在跳过除最后一个与此精确模式匹配的所有内容,一个非捕获组 (?:... 我们是否多次查找任何字符,后跟一个斜杠。

    组可以重复多次,但不贪心。所以它是说这样做,除非你匹配4中解释的以下正则表达式。

    不过,这整个部分不是必需的,因为 ?括号外。比如“/RandomFile.pdf/”这里就不会产生匹配,继续4。

    但是,现在我确实觉得这有点奇怪,因为 .+ 是贪婪的,它仍然期待匹配的斜线。这可能是组的性质,它们是非贪婪的,或者是 Java 模式语法中的错误。

    (.+?)[/\\\\]?$
    

    4:由于正则表达式适用于所有字符串,因此它还必须匹配到末尾。 3 的前一个匹配是非贪婪的,不愿意使用 +?,这意味着它只会匹配,只要它之后的正则表达式也不匹配。我们的词在末尾 $ 在括号内,可能以斜杠结尾,也可能不以斜杠结尾。如果没有文件名,我选择将根路径作为文件名返回,而只是一个斜杠,因为它也是一个文件名(目录名)

    5:括号是一个捕获组,这是我们最后返回的。

    我希望这能澄清一点。

    【讨论】:

    • 这对我来说非常有效。我有一条同时包含 / 和 \ 的路径(从一些 ARM 编译器获得)。这个正则表达式工作得很好。你能写下正则表达式的解释吗? Java 正则表达式让我很困惑。
    • 我加了一个解释 uday ;)
    • 这是唯一对我有用的。我在 Windows 上开发,但在 Linux 上运行服务,用户使用 Internet Explorer 从 Windows 上传文件。在这种情况下,我将使用带有反斜杠的文件名。 codelahoma 的评论帮助我专注于这个解决方案。
    【解决方案4】:

    用正则表达式替换,String name = directory.replaceAll(".*/",""),就这么简单。

    【讨论】:

    • 如果文件名以斜杠结尾则不起作用。如果文件名没有路径(相对文件)将不起作用。不适用于目录名称,只是根目录的“斜线”。不适用于反斜杠和混合斜杠路径( windows )。
    【解决方案5】:

    前面的答案都比使用成熟的正则表达式更简单。但是,如果您真的想使用一个,可以使用以下正则表达式模式:".*/(.+)"

        Pattern p = Pattern.compile(".*/(.+)");
        Matcher matcher = p.matcher("Payload/brownie.app/Info.plist");
    
        if ( matcher.find() ) {
            System.out.println("result: "+matcher.group(1));
        }
    

    正如您从其他答案中看到的那样,这比严格需要的代码要多,但如果您要进行更复杂的模式匹配和字符串提取,那么正则表达式是一个不错的选择。

    【讨论】:

      【解决方案6】:

      如果您正在处理由浏览器传递给 Web 服务器的文件路径,您无法确定它是 DOS 风格的路径、Unix 风格的路径,还是只是没有路径的文件名。如果你真的想要一个正则表达式,应该这样做:

      String path = "Payload/brownie.app/Info.plist";
      String filename = path.replaceFirst("(^.*[/\\\\])?([^/\\\\]*)$","$2");
      

      无论有 DOS、Unix 还是缺少路径,这都可以工作。

      不过,将子字符串用作 dogbane suggests 会更清晰易读,但会添加逻辑来检查两种类型的文件分隔符(同样,仅当您处理多平台输入时)。

      【讨论】:

      • 更好的是,只需使用Johan's 更简单的正则表达式(我不知何故忽略了),但在其中添加反斜杠,如下所示:".*[/\\\\]"
      猜你喜欢
      • 1970-01-01
      • 2013-02-10
      • 1970-01-01
      • 1970-01-01
      • 2018-12-07
      • 1970-01-01
      • 2012-03-10
      • 1970-01-01
      • 2016-08-03
      相关资源
      最近更新 更多