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.