Bagaimana cara saya memotong ekstensi file dari String di Java?

176

Apa cara paling efisien untuk memangkas suffix di Jawa, seperti ini:

title part1.txt
title part2.html
=>
title part1
title part2
Oh Tuhan
sumber
2
Kode efisien bijaksana, adalah apa yang Anda maksud saya berharap, tidak CPU bijaksana
mkoryak
3
Dia tidak bertanya bagaimana melakukannya, dia bertanya apa cara yang paling efisien. Saya datang ke sini mencari hal yang sama.
Edward Falk

Jawaban:

285

Ini adalah semacam kode yang tidak seharusnya kita lakukan sendiri. Gunakan perpustakaan untuk hal-hal duniawi, selamatkan otakmu untuk hal-hal yang sulit.

Dalam hal ini, saya sarankan menggunakan FilenameUtils.removeExtension () dari Apache Commons IO

skaffman
sumber
7
Benar-benar menggedor.
Joshua Pinter
6
Untuk 95% proyek, ini harus menjadi jawaban yang diterima. Menulis ulang kode seperti ini adalah penyebab utama banyak sakit kepala!
Carsten Hoffmann
1
Cukup tambahkan baris berikut dalam gradle untuk menambahkan dependensi: - kompilasi 'commons-io: commons-io: 2.6'
Deepak Sharma
contoh tolong.
john ktejik
8
Jika Anda sudah memiliki Apache Commons I / O di proyek Anda, itu benar. Tetapi jika ini yang Anda butuhkan dari itu, Anda menambahkan (setidaknya) 2,5 MB bobot mati untuk proyek Anda untuk sesuatu yang dapat dengan mudah dilakukan dengan satu baris.
foo
226
str.substring(0, str.lastIndexOf('.'))
Svitlana Maksymchuk
sumber
8
Ini harus ditugaskan ke variabel baru karena str tidak dimodifikasi.
Nathan Feger
51
Tangani dengan hati-hati: itu akan mengeluarkan Exception pada Anda jika nama file tidak memiliki akhiran.
Andreas Dolk
24
bagaimana dengan 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 adalah ketergantungan lain, dan tidak selalu tersedia
ocramot
88

Karena menggunakan String.substringdan String.lastIndexdalam satu-liner itu baik, ada beberapa masalah dalam hal dapat mengatasi jalur file tertentu.

Ambil contoh jalur berikut:

a.b/c

Menggunakan one-liner akan menghasilkan:

a

Itu tidak benar.

Hasilnya seharusnya c, tetapi karena file tidak memiliki ekstensi, tetapi path memiliki direktori dengan .nama, metode one-liner diperdaya untuk memberikan bagian dari path sebagai nama file, yang tidak benar.

Perlu cek

Terinspirasi oleh jawaban skaffman , saya melihat FilenameUtils.removeExtensionmetode Apache Commons IO .

Untuk menciptakan kembali perilakunya, saya menulis beberapa tes yang harus dipenuhi oleh metode baru, yaitu:

Path Nama file
-------------- --------
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

(Dan hanya itu yang sudah saya periksa - mungkin ada cek lain yang seharusnya ada di tempat yang saya abaikan.)

Pelaksanaan

Berikut ini adalah implementasi saya untuk removeExtensionmetode ini:

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

Menjalankan removeExtensionmetode ini dengan tes di atas menghasilkan hasil yang tercantum di atas.

Metode ini diuji dengan kode berikut. Karena ini dijalankan pada Windows, pemisah jalur adalah \yang harus diloloskan dengan \ketika digunakan sebagai bagian dari suatu Stringliteral.

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

Hasilnya adalah:

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

Hasilnya adalah hasil yang diinginkan yang diuraikan dalam tes yang harus dipenuhi metode ini.

coobird
sumber
4
Jawaban yang bagus Apakah ada alasan khusus mengapa Anda menggunakan System.getProperty("file.separator")dan bukan hanya File.separator?
halirutan
2
Peringatan: Solusi ini juga menghilangkan jalur sebelumnya, bukan hanya ekstensi, tidak seperti metode Apache Commons IO.
DHa
3
Tampaknya ini akan gagal untuk/path/to/.htaccess
Kuzeko 4-16
17

BTW, dalam kasus saya, ketika saya menginginkan solusi cepat untuk menghapus ekstensi tertentu, ini kira-kira yang saya lakukan:

  if (filename.endsWith(ext))
    return filename.substring(0,filename.length() - ext.length());
  else
    return filename;
Edward Falk
sumber
16
String foo = "title part1.txt";
foo = foo.substring(0, foo.lastIndexOf('.'));
Jherico
sumber
4
Tidak, mungkin ada lebih dari satu '.'; Anda ingin lastIndexOf ('.')
Adam Jaskiewicz
-1 karena tidak menggunakan metode yang saya pikir Anda gunakan. Itu sekarang total +0 dari saya. Ubah dengan cepat! ;)
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);
}

Apakah ini pertanyaan jebakan? : p

Saya tidak bisa memikirkan cara yang lebih cepat.

Huxi
sumber
7

Gunakan metode di com.google.common.io.Fileskelas jika proyek Anda sudah bergantung pada pustaka inti Google. Metode yang Anda butuhkan adalah getNameWithoutExtension.

Toby
sumber
Mengapa seseorang menentang jawaban saya ??
Toby
Perhatikan bahwa ini hanya mengembalikan nama dasar, jadi jalurnya juga dihapus: google.github.io/guava/releases/19.0/api/docs/com/google/common/…
thSoft
6

Anda dapat mencoba fungsi ini, sangat mendasar

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

Saya menemukan jawaban coolbird sangat berguna.

Tapi saya mengubah pernyataan hasil terakhir menjadi:

if (extensionIndex == -1)
  return s;

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

karena saya ingin nama path lengkap dikembalikan.

Jadi "C: \ Users \ mroh004.COM \ Documents \ Test \ Test.xml" menjadi 
   "C: \ Users \ mroh004.COM \ Documents \ Test \ Test" dan tidak
   "Uji"
mxro
sumber
5
filename.substring(filename.lastIndexOf('.'), filename.length()).toLowerCase();
Alexander
sumber
3
Berlawanan dengan apa yang diminta dan tidak perlu melewati panjangnya, cukup gunakan satu arg substring
4

Gunakan regex. Yang ini menggantikan titik terakhir, dan semuanya setelahnya.

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

Anda juga dapat membuat objek Pola jika Anda ingin mengkompilasi regex.

Steven Spungin
sumber
1
String[] splitted = fileName.split(".");
String fileNameWithoutExtension = fileName.replace("." + splitted[splitted.length - 1], "");
Mahdak
sumber
Perlu dipisah "\\."sebagai "." khusus untuk regex.
Kompas
1

buat file baru dengan jalur gambar string

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 "";
        }
    }
Pravin Bhosale
sumber
1

org.apache.commons.io.FilenameUtils versi 2.4 memberikan jawaban berikut

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 = '\\';
Seseorang disuatu tempat
sumber
1
 private String trimFileExtension(String fileName)
  {
     String[] splits = fileName.split( "\\." );
     return StringUtils.remove( fileName, "." + splits[splits.length - 1] );
  }
supernova
sumber
0

Saya akan melakukan ini:

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

Mulai dari akhir hingga '.' lalu panggil substring.

Sunting: Mungkin bukan golf tapi ini efektif :)

fmsf
sumber
7
Pada dasarnya itulah yang dilakukan oleh lastIndexOf; mengapa menemukan kembali roda?
Michael Myers
Untuk bersenang-senang dan sedikit deskriptif. hanya itu. (dan saya lupa tentang lastIndexOf ketika saya sedang menulis ini)
fmsf
0

Ingat skenario di mana tidak ada ekstensi file atau ada lebih dari satu ekstensi file

contoh Nama 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;
}
Choesang
sumber
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();
}

Ini akan menampilkan contoh untuk img dan imgLink

urs86ro
sumber
0
public static String removeExtension(String file) {
    if(file != null && file.length() > 0) {
        while(file.contains(".")) {
            file = file.substring(0, file.lastIndexOf('.'));
        }
    }
    return file;
}
Alexey
sumber
Ini akan mengubah "a.jpg.jpg" menjadi "a" alih-alih (benar) "a.jpg". Apa tujuan melayani file.length() > 0cek?
Klaus Gütter
Pertanyaan utama adalah "bagaimana menghapus ekstensi?", Jadi ya itu mengubah "a.txt.zip" menjadi "a" dan ".htaccess" menjadi kekosongan. Fungsi ini bekerja dengan Strings, jadi nama file bisa tidak nol tetapi masih bisa 0 panjang, lebih cepat periksa apakah layak sebelum parsing simbol. Salam.
Alexey