Come tagliare un'estensione di file da una stringa in Java?


177

Qual è il modo più efficiente per tagliare il suffisso in Java, in questo modo:

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

2
codice efficiente saggio, è quello che vuoi dire spero, non CPU saggio
mkoryak

3
Non stava chiedendo come farlo, stava chiedendo qual è il modo più efficiente. Sono venuto qui alla ricerca della stessa cosa.
Edward Falk,

Risposte:


285

Questo è il tipo di codice che non dovremmo fare da soli. Usa le librerie per le cose banali, salva il tuo cervello per le cose difficili.

In questo caso, ti consiglio di usare FilenameUtils.removeExtension () da Apache Commons IO


7
Assolutamente botto.
Joshua Pinter,

6
Per il 95% dei progetti, questa dovrebbe essere la risposta accettata. Riscrivere questo codice è la causa principale di molti mal di testa!
Carsten Hoffmann,

1
Basta aggiungere la seguente riga in ordine graduale per aggiungere la dipendenza: - compilare 'commons-io: commons-io: 2.6'
Deepak Sharma,

esempio per favore.
john ktejik,

8
Se hai già I / O di Apache Commons nel tuo progetto, è vero. Ma se questo è tutto ciò di cui hai bisogno, stai aggiungendo (almeno) 2,5 MB di peso morto al tuo progetto per qualcosa che può essere facilmente fatto con una sola linea.
Foo

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

8
Questo dovrebbe essere assegnato a una nuova variabile poiché str non viene modificato.
Nathan Feger,

51
Gestisci con cura: genererà un'eccezione se il nome del file non ha suffisso.
Andreas Dolk,

24
che dire di 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 ('.')). Il nome fileUtils è un'altra dipendenza, e non sempre disponibile
ocramot,

88

Come usando il String.substringeString.lastIndex in una riga è buono, ci sono alcuni problemi in termini di capacità di far fronte a determinati percorsi di file.

Prendi ad esempio il seguente percorso:

a.b/c

L'uso del one-liner comporterà:

a

Non è corretto

Il risultato avrebbe dovuto essere c, ma poiché il file mancava di un'estensione, ma il percorso aveva una directory con un .nel nome, il metodo one-liner è stato ingannato nel dare parte del percorso come nome del file, che non è corretto.

Necessità di controlli

Ispirato dalla risposta di Skaffman , ho dato un'occhiata al FilenameUtils.removeExtensionmetodo di IO di Apache Commons .

Per ricreare il suo comportamento, ho scritto alcuni test che il nuovo metodo dovrebbe soddisfare, che sono i seguenti:

Nome file percorso
-------------- --------
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

(E questo è tutto quello che ho controllato - probabilmente ci sono altri controlli che dovrebbero essere in atto che ho trascurato.)

L'implemento

Di seguito è la mia implementazione per il removeExtensionmetodo:

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'esecuzione di questo removeExtensionmetodo con i test sopra riportati produce i risultati sopra elencati.

Il metodo è stato testato con il seguente codice. Dato che è stato eseguito su Windows, il separatore di percorso è un carattere \che deve essere evitato con un \quando usato come parte di un valore Stringletterale.

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

I risultati furono:

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

I risultati sono i risultati desiderati delineati nel test che il metodo dovrebbe soddisfare.


4
Bella risposta. C'è un motivo particolare per cui usi System.getProperty("file.separator")e non solo File.separator?
Halirutan,

2
Un avvertimento: questa soluzione rimuove anche il percorso precedente, non solo l'estensione, a differenza del metodo IO di Apache Commons.
DHa

3
Sembra che questo fallirà per/path/to/.htaccess
Kuzeko

17

A proposito, nel mio caso, quando volevo una soluzione rapida per rimuovere un'estensione specifica, questo è approssimativamente quello che ho fatto:

  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
No, potrebbe essercene più di uno "."; you want lastIndexOf ('.')
Adam Jaskiewicz,

-1 per non usare il metodo che pensavo stessi usando. Questo è ora un totale di +0 da parte mia. Cambia velocemente! ;)
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);
}

È una domanda trabocchetto? : p

Non riesco a pensare ad un modo più veloce di atm.



6

puoi provare questa funzione, molto semplice

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

5

Ho trovato la risposta di coolbird particolarmente utile.

Ma ho cambiato le ultime dichiarazioni dei risultati in:

if (extensionIndex == -1)
  return s;

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

come volevo che fosse restituito il nome completo del percorso.

Così diventa "C: \ Users \ mroh004.COM \ Documents \ Test \ Test.xml" 
   "C: \ Users \ mroh004.COM \ Documents \ Test \ Test" e non
   "Test"

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

3
Di fronte a ciò che è stato chiesto e non è necessario passare la lunghezza, basta usare una sottostringa arg

4

Usa una regex. Questo sostituisce l'ultimo punto e tutto il resto.

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

Puoi anche creare un oggetto Pattern se vuoi precompilare la regex.


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

È necessario dividere "\\."come "." è speciale per regex.
Bussola,

1

creare un nuovo file con percorso immagine stringa

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 versione 2.4 fornisce la seguente risposta

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

Vorrei fare questo:

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

Cominciando fino alla fine fino al '.' quindi chiamare sottostringa.

Modifica: potrebbe non essere un golf ma è efficace :)


7
Questo è fondamentalmente ciò che fa lastIndexOf; perché reinventare la ruota?
Michael Myers

Per divertimento e per essere un po 'descrittivo. solo quello. (e mi sono dimenticato di lastIndexOf quando stavo scrivendo questo)
fmsf

0

Tenendo presente gli scenari in cui non esiste un'estensione di file o esiste più di un'estensione di file

esempio Nome file: file | 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();
}

Questo mostrerà un esempio sia per img che per 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;
}

Questo trasformerà "a.jpg.jpg" in "a" anziché in (corretto) "a.jpg". A quale scopo serve il file.length() > 0controllo?
Klaus Gütter,

La domanda principale era "come rimuovere l'estensione?", Quindi sì la sua trasformazione "a.txt.zip" in "a" e ".htaccess" in vuoto. Questa funzione funziona con le stringhe, quindi i nomi dei file non possono essere nulli ma possono comunque avere una lunghezza pari a 0, controlla più velocemente se ne vale la pena prima di analizzare i simboli. Saluti.
Alexey,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.