如何在Java中从字符串修剪文件扩展名?


176

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

title part1.txt
title part2.html
=>
title part1
title part2

2
高效的代码,是我希望的,不是CPU的意思
mkoryak

3
他不是在问怎么做,而是在问什么是最有效的方法。我来这里寻找相同的东西。
爱德华·福克

Answers:


285

这是我们不应该自己编写的代码。使用库来处理平凡的事物,而将您的大脑用于硬性事物。

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


7
绝对爆炸。
约书亚·品特

6
对于95%的项目,这应该是公认的答案。像这样重写代码是造成许多麻烦的根本原因!
卡斯滕·霍夫曼

1
只需添加以下行的gradle中添加depedency: -编译“公地IO:公共-10:2.6”
迪帕克·夏尔马

请举个例子。
约翰·克特吉克

8
如果您的项目中已经有Apache Commons I / O,那就对了。但是,如果您需要这些,那么您将为您的项目添加(至少)2.5 MB的自重负载,只需一行即可轻松完成。
foo

226
str.substring(0, str.lastIndexOf('.'))

8
由于未修改str,因此应将其分配给新变量。
内森·费格

51
小心处理:如果文件名没有后缀,则会抛出异常。
Andreas Dolk,2009年

24
那archive.tar.bz2呢?
安东尼奥

20
if(str.contains(".")) str.substring(0, str.lastIndexOf('.'))
Nicolas Tyler 2013年

6
if(str!= null && str.contains(“。”))str.substring(0,str.lastIndexOf('。'))。FilenameUtils是另一个依赖项,并不总是可用
ocramot

88

由于使用String.substringString.lastIndex在单行中很好,因此在能够处理某些文件路径方面存在一些问题。

以以下路径为例:

a.b/c

使用单线将导致:

a

那是不对的。

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

需要检查

skaffman答案的启发,我看了Apache Commons IOFilenameUtils.removeExtension方法。

为了重新创建其行为,我编写了新方法应满足的一些测试,这些测试如下:

路径文件名
-------------- --------
a / b / cc
a / b / c.jpg c
a / b / c.jpg.jpg c.jpg

绝对/ cc
ab / c.jpg c
ab / c.jpg.jpg c.jpg

抄送
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);
}

removeExtension通过上面的测试运行此方法会产生上面列出的结果。

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

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"));

结果是:

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

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


4
好答案。您使用System.getProperty("file.separator")而不是仅仅有特定的原因File.separator吗?
halirutan

2
提示:与Apache Commons IO方法不同,此解决方案还删除了前面的路径,而不仅仅是扩展名。
DHa

3
看来这将为失败/path/to/.htaccess
Kuzeko

17

顺便说一句,就我而言,当我想要快速解决方案以删除特定扩展名时,这大致就是我所做的:

  if (filename.endsWith(ext))
    return filename.substring(0,filename.length() - ext.length());
  else
    return filename;

16
String foo = "title part1.txt";
foo = foo.substring(0, foo.lastIndexOf('.'));

4
不,可能有多个“。”;您想要lastIndexOf('。')
Adam Jaskiewicz

-1未使用我认为您正在使用的方法。现在我总共加了+0。快速更改!;)
Michael Myers

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

这是一个技巧问题吗?:p

我想不出更快的atm方法。



6

您可以尝试此功能,非常基本

public String getWithoutExtension(String fileFullPath){
    return fileFullPath.substring(0, fileFullPath.lastIndexOf('.'));
}

5

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

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

if (extensionIndex == -1)
  return s;

return s.substring(0, lastSeparatorIndex+1) 
         + filename.substring(0, extensionIndex);

因为我希望返回完整的路径名。

因此,“ C:\ Users \ mroh004.COM \ Documents \ Test \ Test.xml”变为 
   “ C:\ Users \ mroh004.COM \ Documents \ Test \ Test”而不是
   “测试”

5
filename.substring(filename.lastIndexOf('.'), filename.length()).toLowerCase();

3
与询问的内容相反,无需传递长度,只需使用一个arg子字符串

4

使用正则表达式。这个替换最后一个点,以及后面的所有内容。

String baseName = fileName.replaceAll("\\.[^.]*$", "");

如果要预编译正则表达式,也可以创建Pattern对象。


1
String[] splitted = fileName.split(".");
String fileNameWithoutExtension = fileName.replace("." + splitted[splitted.length - 1], "");

需要拆分"\\."为“。” 对正则表达式特别有用。
罗盘2014年

1

用字符串图像路径创建一个新文件

String imagePath;
File test = new File(imagePath);
test.getName();
test.getPath();
getExtension(test.getName());


public static String getExtension(String uri) {
        if (uri == null) {
            return null;
        }

        int dot = uri.lastIndexOf(".");
        if (dot >= 0) {
            return uri.substring(dot);
        } else {
            // No extension.
            return "";
        }
    }

1

org.apache.commons.io.FilenameUtils 2.4版给出以下答案

public static String removeExtension(String filename) {
    if (filename == null) {
        return null;
    }
    int index = indexOfExtension(filename);
    if (index == -1) {
        return filename;
    } else {
        return filename.substring(0, index);
    }
}

public static int indexOfExtension(String filename) {
    if (filename == null) {
        return -1;
    }
    int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
    int lastSeparator = indexOfLastSeparator(filename);
    return lastSeparator > extensionPos ? -1 : extensionPos;
}

public static int indexOfLastSeparator(String filename) {
    if (filename == null) {
        return -1;
    }
    int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
    int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
    return Math.max(lastUnixPos, lastWindowsPos);
}

public static final char EXTENSION_SEPARATOR = '.';
private static final char UNIX_SEPARATOR = '/';
private static final char WINDOWS_SEPARATOR = '\\';

1
 private String trimFileExtension(String fileName)
  {
     String[] splits = fileName.split( "\\." );
     return StringUtils.remove( fileName, "." + splits[splits.length - 1] );
  }

0

我会这样:

String title_part = "title part1.txt";
int i;
for(i=title_part.length()-1 ; i>=0 && title_part.charAt(i)!='.' ; i--);
title_part = title_part.substring(0,i);

从头到尾直到。然后调用子字符串。

编辑:可能不是高尔夫,但很有效:)


7
基本上,这就是lastIndexOf所做的;为什么要重新发明轮子?
迈克尔·迈尔斯

好玩,有点描述性。只是。(当我写这篇文章时,我忘记了lastIndexOf)
fmsf

0

请记住没有文件扩展名或存在多个文件扩展名的情况

示例文件名:file.txt | file.tar.bz2

/**
 *
 * @param fileName
 * @return file extension
 * example file.fastq.gz => fastq.gz
 */
private String extractFileExtension(String fileName) {
    String type = "undefined";
    if (FilenameUtils.indexOfExtension(fileName) != -1) {
        String fileBaseName = FilenameUtils.getBaseName(fileName);
        int indexOfExtension = -1;
        while (fileBaseName.contains(".")) {
            indexOfExtension = FilenameUtils.indexOfExtension(fileBaseName);
            fileBaseName = FilenameUtils.getBaseName(fileBaseName);
        }
        type = fileName.substring(indexOfExtension + 1, fileName.length());
    }
    return type;
}

0
String img = "example.jpg";
// String imgLink = "http://www.example.com/example.jpg";
URI uri = null;

try {
    uri = new URI(img);
    String[] segments = uri.getPath().split("/");
    System.out.println(segments[segments.length-1].split("\\.")[0]);
} catch (Exception e) {
    e.printStackTrace();
}

这将输出例如两个IMGimgLink


0
public static String removeExtension(String file) {
    if(file != null && file.length() > 0) {
        while(file.contains(".")) {
            file = file.substring(0, file.lastIndexOf('.'));
        }
    }
    return file;
}

这会将“ a.jpg.jpg”转换为“ a”,而不是(正确的)“ a.jpg”。file.length() > 0支票有什么目的?
克劳斯·古特(KlausGütter),

主要问题是“如何删除扩展名?”,因此是的,将其“ a.txt.zip”转换为“ a”,并将“ .htaccess”转换为空。此函数与字符串一起使用,因此文件名不能为null,但长度仍可以为0,更快地在解析符号之前检查是否值得。问候。
Alexey,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.