Comment découper une extension de fichier d'une chaîne en Java?


177

Quel est le moyen le plus efficace de couper le suffixe en Java, comme ceci:

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

2
code efficace sage, est ce que vous voulez dire que je l' espère, pas sage CPU
mkoryak

3
Il ne demandait pas comment faire, il demandait quelle était la manière la plus efficace. Je suis venu ici à la recherche de la même chose.
Edward Falk

Réponses:


285

C'est le genre de code que nous ne devrions pas faire nous-mêmes. Utilisez des bibliothèques pour les choses banales, gardez votre cerveau pour les choses difficiles.

Dans ce cas, je recommande d'utiliser FilenameUtils.removeExtension () d' Apache Commons IO


7
Absolument bang dessus.
Joshua Pinter

6
Pour 95% des projets, cela devrait être la réponse acceptée. La réécriture de code comme celui-ci est à l'origine de nombreux maux de tête!
Carsten Hoffmann

1
Ajoutez simplement la ligne suivante dans gradle pour ajouter la dépendance: - compilez 'commons-io: commons-io: 2.6'
Deepak Sharma

exemple s'il vous plaît.
john ktejik

8
Si vous avez déjà des E / S Apache Commons dans votre projet, c'est vrai. Mais si tout ce dont vous avez besoin, vous ajoutez (au moins) 2,5 Mo de poids mort à votre projet pour quelque chose qui peut être facilement réalisé avec une seule ligne.
foo le

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

8
Cela doit être affecté à une nouvelle variable car str n'est pas modifié.
Nathan Feger

51
Manipulez avec précaution: cela vous lancera une exception si le nom du fichier n'a pas de suffixe.
Andreas Dolk

24
qu'en est-il de 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 est une autre dépendance, et pas toujours disponible
ocramot

88

Comme l'utilisation de String.substringet String.lastIndexdans une seule ligne est une bonne chose, il y a quelques problèmes en termes de capacité à gérer certains chemins de fichiers.

Prenons par exemple le chemin suivant:

a.b/c

L'utilisation du one-liner entraînera:

a

C'est incorrect.

Le résultat aurait dû être c, mais comme le fichier n'avait pas d'extension, mais que le chemin avait un répertoire avec un .dans le nom, la méthode one-liner a été trompée en donnant une partie du chemin comme nom de fichier, ce qui n'est pas correct.

Besoin de chèques

Inspiré par la réponse de skaffman , j'ai jeté un coup d'œil à la FilenameUtils.removeExtensionméthode de l' Apache Commons IO .

Afin de recréer son comportement, j'ai écrit quelques tests que la nouvelle méthode devrait remplir, qui sont les suivants:

Nom de fichier du chemin
-------------- --------
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

(Et c'est tout ce que j'ai vérifié - il y a probablement d'autres contrôles qui devraient être en place que j'ai négligés.)

La mise en oeuvre

Voici mon implémentation pour la removeExtensionméthode:

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

L'exécution de cette removeExtensionméthode avec les tests ci-dessus donne les résultats énumérés ci-dessus.

La méthode a été testée avec le code suivant. Comme cela a été exécuté sous Windows, le séparateur de chemin est un \qui doit être échappé avec un \lorsqu'il est utilisé dans le cadre d'un Stringlittéral.

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

Les résultats ont été:

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

Les résultats sont les résultats souhaités décrits dans le test que la méthode doit remplir.


4
Très bonne réponse. Y a-t-il une raison particulière pour laquelle vous utilisez System.getProperty("file.separator")et pas seulement File.separator?
halirutan le

2
Un mot d'avertissement: cette solution supprime également le chemin précédent, pas seulement l'extension, contrairement à la méthode Apache Commons IO.
DHa

3
Il semble que cela échouera pour le/path/to/.htaccess
Kuzeko

17

BTW, dans mon cas, lorsque je voulais une solution rapide pour supprimer une extension spécifique, c'est à peu près ce que j'ai fait:

  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
Non, il peut y en avoir plus d'un "."; vous voulez lastIndexOf ('.')
Adam Jaskiewicz

-1 pour ne pas utiliser la méthode que je pensais que vous utilisiez. C'est maintenant un total de +0 de ma part. Changez-le vite! ;)
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);
}

Est-ce une question piège? : p

Je ne peux pas penser à un guichet automatique plus rapide.



6

vous pouvez essayer cette fonction, très basique

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

5

J'ai trouvé la réponse de coolbird particulièrement utile.

Mais j'ai changé les dernières déclarations de résultat en:

if (extensionIndex == -1)
  return s;

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

car je voulais que le nom complet du chemin soit renvoyé.

Ainsi "C: \ Users \ mroh004.COM \ Documents \ Test \ Test.xml" devient 
   "C: \ Users \ mroh004.COM \ Documents \ Test \ Test" et non
   "Tester"

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

3
En face de ce qui a été demandé et il n'est pas nécessaire de passer la longueur, utilisez simplement une sous

4

Utilisez une expression régulière. Celui-ci remplace le dernier point, et tout ce qui suit.

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

Vous pouvez également créer un objet Pattern si vous souhaitez précompiler le regex.


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

Besoin de diviser "\\."en "." est spécial pour regex.
Compass

1

créer un nouveau fichier avec le chemin de l'image de chaîne

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 donne la réponse suivante

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

Je voudrais faire comme ceci:

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

De la fin jusqu'au '.' puis appelez substring.

Edit: Ce n'est peut-être pas un golf mais c'est efficace :)


7
C'est essentiellement ce que fait lastIndexOf; pourquoi réinventer la roue?
Michael Myers

Pour le plaisir et pour être un peu descriptif. juste ça. (et j'ai oublié lastIndexOf quand j'écrivais ceci)
fmsf

0

En gardant à l'esprit les scénarios où il n'y a pas d'extension de fichier ou il y a plus d'une extension de fichier

exemple Nom de fichier: fichier | 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();
}

Cela affichera un exemple pour img et imgLink


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

Cela transformera "a.jpg.jpg" en "a" au lieu du (correct) "a.jpg". Dans quel but sert le file.length() > 0chèque?
Klaus Gütter

La question principale était "comment supprimer l'extension?", Donc oui, sa transformation "a.txt.zip" en "a" et ".htaccess" en vide. Cette fonction fonctionne avec les chaînes, donc les noms de fichiers peuvent ne pas être nuls mais peuvent toujours avoir une longueur de 0, vérifiez plus rapidement si cela en vaut la peine avant d'analyser les symboles. Cordialement.
Alexey
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.