Wie schneide ich eine Dateierweiterung aus einem String in Java?


176

Was ist der effizienteste Weg, um das Suffix in Java wie folgt zu kürzen:

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

2
Effizienter Code, ist das, was Sie meinen, ich hoffe, nicht CPU-weise
mkoryak

3
Er fragte nicht, wie es geht, er fragte, was der effizienteste Weg sei. Ich bin hierher gekommen, um dasselbe zu suchen.
Edward Falk

Antworten:


284

Dies ist die Art von Code, die wir nicht selbst machen sollten. Verwenden Sie Bibliotheken für das Alltägliche, retten Sie Ihr Gehirn für das Harte.

In diesem Fall empfehle ich die Verwendung von FilenameUtils.removeExtension () von Apache Commons IO


7
Absolut knallhart.
Joshua Pinter

6
Für 95% der Projekte sollte dies die akzeptierte Antwort sein. Das Umschreiben von Code wie diesem ist die Hauptursache für viele Kopfschmerzen!
Carsten Hoffmann

1
Fügen Sie einfach die folgende Zeile in Gradle hinzu, um die Abhängigkeit hinzuzufügen: - Kompilieren Sie 'commons-io: commons-io: 2.6'
Deepak Sharma

Beispiel bitte.
John Ktejik

8
Wenn Sie Apache Commons I / O bereits in Ihrem Projekt haben, ist das richtig. Wenn dies jedoch alles ist, was Sie dafür benötigen, fügen Sie Ihrem Projekt (mindestens) 2,5 MB Eigengewicht hinzu, um etwas zu erreichen, das problemlos mit einer einzigen Zeile erledigt werden kann.
foo

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

8
Dies sollte einer neuen Variablen zugewiesen werden, da str nicht geändert wird.
Nathan Feger

51
Gehen Sie vorsichtig vor: Es wird eine Ausnahme auf Sie geworfen, wenn der Dateiname kein Suffix hat.
Andreas Dolk

24
Was ist mit archive.tar.bz2?
Antonio

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

6
if (str! = null && str.contains (".")) str.substring (0, str.lastIndexOf ('.')). FilenameUtils ist eine weitere Abhängigkeit und nicht immer verfügbar
Ocramot

88

Da die Verwendung von String.substringund String.lastIndexin einem Einzeiler gut ist, gibt es einige Probleme hinsichtlich der Fähigkeit, mit bestimmten Dateipfaden umzugehen.

Nehmen Sie zum Beispiel den folgenden Weg:

a.b/c

Die Verwendung des Einzeilers führt zu:

a

Das ist falsch

Das Ergebnis hätte sein sollen c, aber da der Datei eine Erweiterung fehlte, der Pfad jedoch ein Verzeichnis mit einem .im Namen hatte, wurde die Einzeiler-Methode dazu verleitet, einen Teil des Pfads als Dateinamen anzugeben, was nicht korrekt ist.

Notwendigkeit von Schecks

Inspiriert von Skaffmans Antwort , habe ich mir die FilenameUtils.removeExtensionMethode des Apache Commons IO angesehen .

Um sein Verhalten wiederherzustellen, habe ich einige Tests geschrieben, die die neue Methode erfüllen sollte:

Pfad Dateiname
-------------- --------
a / b / cc
a / b / c.jpg c
a / b / c.jpg.jpg c.jpg

ab / cc
ab / c.jpg c
ab / c.jpg.jpg c.jpg

cc
c.jpg c
c.jpg.jpg c.jpg

(Und das ist alles, worauf ich überprüft habe - es gibt wahrscheinlich andere Überprüfungen, die vorhanden sein sollten, die ich übersehen habe.)

Die Umsetzung

Das Folgende ist meine Implementierung für die removeExtensionMethode:

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

Wenn Sie diese removeExtensionMethode mit den oben genannten Tests ausführen, erhalten Sie die oben aufgeführten Ergebnisse.

Die Methode wurde mit dem folgenden Code getestet. Da dies unter Windows ausgeführt wurde, ist das Pfadtrennzeichen ein, \das \bei Verwendung als Teil eines StringLiteral mit einem Escapezeichen versehen werden muss.

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

Die Ergebnisse waren:

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

Die Ergebnisse sind die gewünschten Ergebnisse, die in dem Test aufgeführt sind, den die Methode erfüllen sollte.


4
Gute Antwort. Gibt es einen bestimmten Grund, warum Sie verwenden System.getProperty("file.separator")und nicht nur File.separator?
Halirutan

2
Ein Wort der Warnung: Diese Lösung entfernt im Gegensatz zur Apache Commons IO-Methode auch den vorhergehenden Pfad und nicht nur die Erweiterung.
DHa

3
Es scheint, dass dies für die/path/to/.htaccess
Kuzeko

17

Übrigens, in meinem Fall, als ich eine schnelle Lösung zum Entfernen einer bestimmten Erweiterung wollte, habe ich ungefähr Folgendes getan:

  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
Nein, es könnte mehr als ein '.' Geben. du willst lastIndexOf ('.')
Adam Jaskiewicz

-1 für die Nichtanwendung der Methode, von der ich dachte, dass Sie sie verwenden. Das sind jetzt insgesamt +0 von mir. Ändere es schnell! ;)
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);
}

Ist das eine Trickfrage? : p

Ich kann mir keinen schnelleren Weg vorstellen.


7

Verwenden Sie eine Methode im com.google.common.io.FilesUnterricht, wenn Ihr Projekt bereits von der Google-Kernbibliothek abhängig ist. Die Methode, die Sie benötigen, ist getNameWithoutExtension.


Warum ist jemand gegen meine Antwort?
Toby

Beachten Sie, dass dies nur den Basisnamen
zurückgibt

6

Sie können diese Funktion ausprobieren, sehr einfach

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

5

Ich habe die Antwort von coolbird gefunden besonders nützlich.

Aber ich habe die letzten Ergebnisaussagen geändert in:

if (extensionIndex == -1)
  return s;

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

da ich wollte, dass der vollständige Pfadname zurückgegeben wird.

So wird "C: \ Users \ mroh004.COM \ Documents \ Test \ Test.xml" 
   "C: \ Users \ mroh004.COM \ Documents \ Test \ Test" und nicht
   "Prüfung"

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

3
Im Gegensatz zu dem, was gefragt wurde und es nicht notwendig ist, die Länge zu übergeben, verwenden Sie einfach einen arg-Teilstring

4

Verwenden Sie einen regulären Ausdruck. Dieser ersetzt den letzten Punkt und alles danach.

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

Sie können auch ein Musterobjekt erstellen, wenn Sie den regulären Ausdruck vorkompilieren möchten.


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

Müssen "\\."als "." ist speziell für Regex.
Kompass

1

Erstellen Sie eine neue Datei mit dem Pfad des Zeichenfolgenbilds

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 Version 2.4 gibt die folgende Antwort

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

Das würde mir gefallen:

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

Vom Ende bis zum '.' Rufen Sie dann Teilzeichenfolge auf.

Edit: Könnte kein Golf sein, aber es ist effektiv :)


7
Genau das macht lastIndexOf sowieso. Warum das Rad neu erfinden?
Michael Myers

Zum Spaß und um ein bisschen beschreibend zu sein. nur das. (und ich habe lastIndexOf vergessen, als ich das schrieb)
fmsf

0

Beachten Sie die Szenarien, in denen es keine Dateierweiterung oder mehr als eine Dateierweiterung gibt

Beispiel Dateiname: Datei | 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();
}

Dies gibt ein Beispiel für img und imgLink aus


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

Dadurch wird "a.jpg.jpg" in "a" anstelle des (korrekten) "a.jpg" umgewandelt. Welchem ​​Zweck dient die file.length() > 0Prüfung?
Klaus Gütter

Die Hauptfrage war "Wie entferne ich die Erweiterung?", Also ja, die Transformation "a.txt.zip" in "a" und ".htaccess" in Leere. Diese Funktion funktioniert mit Strings, sodass Dateinamen nicht null, aber dennoch 0 lang sein können. Überprüfen Sie schneller, ob es sich lohnt, bevor Sie Symbole analysieren. Grüße.
Alexey
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.