Java'daki bir dizeden dosya uzantısını nasıl kesebilirim?


177

Java'da soneki kırpmanın en etkili yolu nedir, şöyle:

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

2
verimli kod bilge, ne demek istediğim, CPU akıllıca değil
mkoryak

3
Nasıl yapılacağını sormuyordu, en etkili yolun ne olduğunu soruyordu. Buraya aynı şeyi aramaya geldim.
Edward Falk

Yanıtlar:


285

Bu, kendimiz yapmamamız gereken bir kod türüdür. Sıradan şeyler için kütüphaneler kullanın, beyninizi zor şeyler için saklayın.

Bu durumda, ben kullanmanızı öneririz FilenameUtils.removeExtension () den Apache Commons IO


7
Kesinlikle vur.
Joshua Pinter

6
Projelerin% 95'i için bu kabul edilen cevap olmalıdır. Kodu yeniden yazmak, birçok baş ağrısının temel nedenidir!
Carsten Hoffmann

1
Bağımlılığı eklemek için sadece aşağıdaki satırı sıraya ekleyin: - 'commons-io: commons-io: 2.6' derleyin
Deepak Sharma

örnek lütfen.
john ktejik

8
Projenizde zaten Apache Commons I / O varsa, doğru. Ancak tüm bunlara ihtiyacınız varsa, tek bir satırla kolayca yapılabilecek bir şey için projenize (en az) 2,5 MB ölü ağırlık eklersiniz.
Foo

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

8
Bu, str değiştirilmediğinden yeni bir değişkene atanmalıdır.
Nathan Feger

51
Dikkatli kullanın: dosya adının soneki yoksa size bir İstisna atar.
Andreas Dolk

24
archive.tar.bz2 hakkında ne dersiniz?
Antonio

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

6
if (str! = null && str.contains (".")) str.substring (0, str.lastIndexOf ('.')). FilenameUtils başka bir bağımlılıktır ve her zaman mevcut değildir
ocramot

88

Kullanarak gibi String.substringve String.lastIndexbir tek satırlık iyidir de, belirli dosya yolları ile baş edememek açısından bazı sorunlar vardır.

Örneğin aşağıdaki yolu ele alalım:

a.b/c

Tek astarın kullanılması aşağıdakilere neden olur:

a

Bu yanlış.

Sonuç olmalıydı c, ancak dosyada bir uzantı bulunmadığından, ancak yolun .adında bir dizini bulunduğundan , tek satırlı yöntem, yolun bir parçası olarak doğru olmayan dosya adı olarak kandırıldı.

Kontrol ihtiyacı

Skaffman'ın cevabından esinlenerek Apache Commons IOFilenameUtils.removeExtension yöntemine bir göz attım .

Davranışını yeniden yaratmak için, yeni yöntemin yerine getirmesi gereken birkaç test yazdım:

Yol Dosya Adı
-------------- --------
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

(Ve kontrol ettiğim tek şey bu - muhtemelen göz ardı ettiğim başka kontroller var.)

Hayata geçirme

Yöntem için benim uygulama aşağıdadır 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);
}

Bu removeExtensionyöntemin yukarıdaki testlerle çalıştırılması , yukarıda listelenen sonuçları verir.

Yöntem aşağıdaki kod ile test edilmiştir. Bu Windows üzerinde çalıştırıldığından, yol ayırıcı bir değişmezin parçası olarak kullanıldığında \bir ile kaçması gerekir .\String

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

Sonuçlar:

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

Sonuçlar, yöntemin yerine getirmesi gereken testte belirtilen istenen sonuçlardır.


4
Mükemmel cevap. System.getProperty("file.separator")Sadece kullanmanın değil, kullanmanın özel bir nedeni var mı File.separator?
halirutan

2
Uyarı kelimesi: Bu çözüm, Apache Commons IO yönteminin aksine, yalnızca uzantıyı değil önceki yolu da kaldırır.
DHa

3
Görünüşe göre bu başarısız olacak/path/to/.htaccess
Kuzeko

17

BTW, benim durumumda, belirli bir uzantıyı kaldırmak için hızlı bir çözüm istediğimde, bu yaklaşık olarak yaptığım şeydi:

  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
Hayır, birden fazla '' olabilir. '; lastIndexOf ('.')
Adam Jaskiewicz

-1 kullandığınızı düşündüğüm yöntemi kullanmadığınız için. Bu benden toplam +0. Çabuk değiştirin! ;)
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);
}

Bu hileli bir soru mu? : p

Daha hızlı bir yol düşünemiyorum.



6

bu işlevi deneyebilirsiniz, çok temel

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

5

Coolbird'ün cevabını özellikle yararlı buldum .

Ama son sonuç ifadelerini şöyle değiştirdim:

if (extensionIndex == -1)
  return s;

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

tam yol adının döndürülmesini istedim.

Böylece "C: \ Users \ mroh004.COM \ Documents \ Test \ Test.xml" olur 
   "C: \ Kullanıcılar \ mroh004.COM \ Belgeler \ Test \ Test" değil
   "Ölçek"

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

3

4

Normal ifade kullanın. Bu son noktanın ve ondan sonraki her şeyin yerini alır.

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

Normal ifadeyi önceden derlemek istiyorsanız bir Pattern nesnesi de oluşturabilirsiniz.


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

İhtiyaç üzerine bölmek "\\."gibi "sunulmuştur." normal ifade için özeldir.
Pusula

1

dize görüntü yolu ile yeni bir dosya oluştur

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 sürüm 2.4 aşağıdaki yanıtı verir

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

Bunu şöyle yaparım:

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

Sonuna kadar '.' sonra alt dize çağırın.

Edit: Golf olamaz ama etkili :)


7
Temel olarak lastIndexOf zaten bunu yapar; Neden tekerleği yeniden icat ettiniz?
Michael Myers

Eğlenmek ve biraz açıklayıcı olmak için. sadece bu. (ve bunu yazarken lastIndexOf'u unuttum)
fmsf

0

Dosya uzantısının olmadığı veya birden fazla dosya uzantısının bulunduğu senaryoları unutmayın

örnek Dosyaadı: dosya | dosya.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();
}

Çıktısı verir örneği hem img ve 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;
}

Bu, "a.jpg.jpg" dosyasını (doğru) "a.jpg" yerine "a" biçimine dönüştürür. Çeke hangi amaca hizmet eder file.length() > 0?
Klaus Gütter

Ana soru "uzantı nasıl kaldırılır?", Bu yüzden evet "a.txt.zip" dönüştürmek için boşluk "a" ve ".htaccess" boşluk. Bu işlev Dizeler ile çalışır, bu nedenle dosya adları boş olamaz, ancak 0 uzunluk olabilir, sembolleri ayrıştırmadan önce buna değip değmediğini daha hızlı kontrol edin. Saygılarımızla.
Alexey
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.