如何从Java中的String修剪文件扩展名?

omg*_*omg 171 java string process

在Java中修剪后缀的最有效方法是什么,如下所示:

title part1.txt
title part2.html
=>
title part1
title part2
Run Code Online (Sandbox Code Playgroud)

ska*_*man 271

这是我们自己不应该做的那种代码.使用库来获得平凡的东西,为大脑保存你的大脑.

在这种情况下,我建议使用FilenameUtils.removeExtension()Apache的百科全书IO

  • 绝对爆炸. (7认同)
  • 对于项目的95%,这应该是公认的答案.重写这样的代码是许多令人头疼的根本原因! (4认同)
  • 如果您的项目中已经有Apache Commons I/O,那是对的.但是,如果您只需要它,那么您可以为项目添加(至少)2.5 MB的自重,这可以通过一条线轻松完成. (4认同)

Svi*_*huk 223

str.substring(0, str.lastIndexOf('.'))
Run Code Online (Sandbox Code Playgroud)

  • 请小心处理:如果文件名没有后缀,它会向您抛出异常. (51认同)
  • 那么archive.tar.bz2呢? (23认同)
  • `if(str.contains("."))``str.substring(0,str.lastIndexOf('.'))` (19认同)
  • 由于未修改str,因此应将其分配给新变量. (8认同)
  • if(str!= null && str.contains("."))str.substring(0,str.lastIndexOf('.')).FilenameUtils是另一个依赖项,并不总是可用 (6认同)

coo*_*ird 86

使用String.substringString.lastIndex在单行中使用是好的,在能够处理某些文件路径方面存在一些问题.

以下面的路径为例:

a.b/c
Run Code Online (Sandbox Code Playgroud)

使用单行将导致:

a
Run Code Online (Sandbox Code Playgroud)

那是不对的.

结果本来应该是c,但由于文件缺少扩展名,但是路径中有一个.名称中有a的目录,因此单线程方法被欺骗为提供路径的一部分作为文件名,这是不正确的.

需要检查

受到skaffman的回答的启发,我看了一下Apache Commons IOFilenameUtils.removeExtension方法.

为了重新创建它的行为,我写了一些新方法应该完成的测试,其中包括:

Path                  Filename
--------------        --------
a/b/c                 c
a/b/c.jpg             c
a/b/c.jpg.jpg         c.jpg

a.b/c                 c
a.b/c.jpg             c
a.b/c.jpg.jpg         c.jpg

c                     c
c.jpg                 c
c.jpg.jpg             c.jpg

(这就是我所检查过的 - 可能还有其他我应该忽略的检查.)

实施

以下是我对该removeExtension方法的实现:

public static String removeExtension(String s) {

    String separator = System.getProperty("file.separator");
    String filename;

    // Remove the path upto the filename.
    int lastSeparatorIndex = s.lastIndexOf(separator);
    if (lastSeparatorIndex == -1) {
        filename = s;
    } else {
        filename = s.substring(lastSeparatorIndex + 1);
    }

    // Remove the extension.
    int extensionIndex = filename.lastIndexOf(".");
    if (extensionIndex == -1)
        return filename;

    return filename.substring(0, extensionIndex);
}
Run Code Online (Sandbox Code Playgroud)

removeExtension使用上述测试运行此方法会产生上面列出的结果.

使用以下代码测试该方法.由于这是在Windows上运行的,因此路径分隔符\必须\在使用时作为String文字的一部分进行转义.

System.out.println(removeExtension("a\\b\\c"));
System.out.println(removeExtension("a\\b\\c.jpg"));
System.out.println(removeExtension("a\\b\\c.jpg.jpg"));

System.out.println(removeExtension("a.b\\c"));
System.out.println(removeExtension("a.b\\c.jpg"));
System.out.println(removeExtension("a.b\\c.jpg.jpg"));

System.out.println(removeExtension("c"));
System.out.println(removeExtension("c.jpg"));
System.out.println(removeExtension("c.jpg.jpg"));
Run Code Online (Sandbox Code Playgroud)

结果是:

c
c
c.jpg
c
c
c.jpg
c
c
c.jpg
Run Code Online (Sandbox Code Playgroud)

结果是该方法应该满足的测试中概述的期望结果.

  • 很好的答案.是否有一个特殊原因可以使用`System.getProperty("file.separator")`而不仅仅是`File.separator`? (4认同)
  • 提醒一句:与Apache Commons IO方法不同,此解决方案还会删除前面的路径,而不仅仅是扩展路径. (2认同)
  • 看来这对`/​​ path/to/.htaccess`会失败 (2认同)

Edw*_*alk 17

顺便说一句,在我的情况下,当我想要一个快速解决方案来删除特定的扩展时,这大致就是我所做的:

  if (filename.endsWith(ext))
    return filename.substring(0,filename.length() - ext.length());
  else
    return filename;
Run Code Online (Sandbox Code Playgroud)


Jhe*_*ico 16

String foo = "title part1.txt";
foo = foo.substring(0, foo.lastIndexOf('.'));
Run Code Online (Sandbox Code Playgroud)

  • 不,可能不止一个'.'; 你想要lastIndexOf('.') (4认同)

Sha*_*onu 9

你可以试试这个功能,非常基础

public String getWithoutExtension(String fileFullPath){
    return fileFullPath.substring(0, fileFullPath.lastIndexOf('.'));
}
Run Code Online (Sandbox Code Playgroud)


Hux*_*uxi 6

String fileName="foo.bar";
int dotIndex=fileName.lastIndexOf('.');
if(dotIndex>=0) { // to prevent exception if there is no dot
  fileName=fileName.substring(0,dotIndex);
}
Run Code Online (Sandbox Code Playgroud)

这是一个棘手的问题吗?:p

我想不出更快的方式.


Tob*_*oby 6

com.google.common.io.Files如果您的项目已经依赖于Google核心库,请使用类中的方法。您需要的方法是getNameWithoutExtension


mxr*_*xro 5

我发现coolbird的答案特别有用.

但是我将最后的结果语句更改为:

if (extensionIndex == -1)
  return s;

return s.substring(0, lastSeparatorIndex+1) 
         + filename.substring(0, extensionIndex);
Run Code Online (Sandbox Code Playgroud)

因为我想要返回完整的路径名.

So "C:\Users\mroh004.COM\Documents\Test\Test.xml" becomes 
   "C:\Users\mroh004.COM\Documents\Test\Test" and not
   "Test"


小智 5

filename.substring(filename.lastIndexOf('.'), filename.length()).toLowerCase();
Run Code Online (Sandbox Code Playgroud)

  • 与所要求的相反,并且不需要传递长度,只需使用一个arg子串 (3认同)