Como aparar uma extensão de arquivo de uma String em Java?


176

Qual é a maneira mais eficiente de aparar o sufixo em Java, assim:

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

2
código eficiente sábio, é o que você quer dizer eu espero, não CPU sábio
mkoryak

3
Ele não estava perguntando como fazê-lo, estava perguntando qual era a maneira mais eficiente. Eu vim aqui procurando a mesma coisa.
Edward Falk

Respostas:


285

Este é o tipo de código que não deveríamos estar fazendo nós mesmos. Use bibliotecas para as coisas mundanas, salve seu cérebro para as coisas difíceis.

Nesse caso, eu recomendo usar FilenameUtils.removeExtension () do Apache Commons IO


7
Absolutamente bang.
Joshua Pinter

6
Para 95% dos projetos, essa deve ser a resposta aceita. Reescrever códigos como esse é a causa raiz de muitas dores de cabeça!
Carsten Hoffmann

1
Basta adicionar a seguinte linha em gradle para adicionar a impedância: - compile 'commons-io: commons-io: 2.6'
Deepak Sharma

exemplo por favor.
john ktejik

8
Se você já possui o Apache Commons I / O em seu projeto, isso mesmo. Mas, se tudo isso for necessário, você estará adicionando (pelo menos) 2,5 MB de peso morto ao seu projeto para algo que pode ser feito facilmente com uma única linha.
foo

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

8
Isso deve ser atribuído a uma nova variável, pois str não é modificado.
197 Nathan Feger

51
Manuseie com cuidado: ele emitirá uma exceção se o nome do arquivo não tiver sufixo.
Andreas Dolk

24
e quanto a 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 é outra dependência, e não sempre disponível
ocramot

88

Como usar o String.substringe String.lastIndexem uma linha é bom, existem alguns problemas em termos de capacidade de lidar com certos caminhos de arquivo.

Pegue, por exemplo, o seguinte caminho:

a.b/c

O uso de uma linha resultará em:

a

Isso está incorreto.

O resultado deveria ter sido c, mas como o arquivo não tinha extensão, mas o caminho tinha um diretório com a .no nome, o método de uma linha foi enganado para fornecer parte do caminho como o nome do arquivo, o que não está correto.

Necessidade de cheques

Inspirado pela resposta de skaffman , dei uma olhada no FilenameUtils.removeExtensionmétodo do Apache Commons IO .

Para recriar seu comportamento, escrevi alguns testes que o novo método deve executar, que são os seguintes:

Nome do arquivo do caminho
-------------- --------
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 foi tudo o que eu verifiquei - provavelmente há outras verificações que devem ser feitas e que eu ignorei.)

A implementação

A seguir está minha implementação para o removeExtensionmétodo:

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

A execução desse removeExtensionmétodo com os testes acima produz os resultados listados acima.

O método foi testado com o seguinte código. Como isso foi executado no Windows, o separador de caminho é aquele \que deve ser escapado com um \quando usado como parte de um 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"));

Os resultados foram:

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

Os resultados são os resultados desejados descritos no teste que o método deve cumprir.


4
Ótima resposta. Existe uma razão específica para você usar System.getProperty("file.separator")e não apenas File.separator?
halirutan

2
Uma palavra de aviso: Esta solução também remove o caminho anterior, não apenas a extensão, ao contrário do método Apache Commons IO.
DHA

3
Parece que este irá falhar para o/path/to/.htaccess
Kuzeko

17

BTW, no meu caso, quando eu queria uma solução rápida para remover uma extensão específica, foi o que fiz aproximadamente:

  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
Não, pode haver mais de um '.'; você quer lastIndexOf ( '')
Adam Jaskiewicz

-1 por não usar o método que pensei que estava usando. Agora é um total de +0 de mim. Mude rápido! ;)
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);
}

Esta é uma pergunta complicada? : p

Não consigo pensar em uma maneira mais rápida de atm.



6

você pode tentar esta função, muito básica

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

5

Achei a resposta do coolbird particularmente útil.

Mas mudei as últimas instruções de resultado para:

if (extensionIndex == -1)
  return s;

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

como eu queria que o nome do caminho completo fosse retornado.

Assim, "C: \ Users \ mroh004.COM \ Documents \ Test \ Test.xml" se torna 
   "C: \ Users \ mroh004.COM \ Documents \ Test \ Test" e não
   "Teste"

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

3
Ao contrário do que foi perguntado e não há necessidade de passar o comprimento, é só usar um ARG substring

4

Use uma regex. Este substitui o último ponto e tudo depois dele.

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

Você também pode criar um objeto Pattern se desejar pré-compilar o regex.


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

Precisa dividir "\\."como "." é especial para regex.
Compass

1

crie um novo arquivo com o caminho da imagem da 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 "";
        }
    }

1

org.apache.commons.io.FilenameUtils versão 2.4 fornece a seguinte resposta

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

Eu faria assim:

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

Do início ao fim até o '.' depois chame a substring.

Edit: Pode não ser um golfe, mas é eficaz :)


7
Isso é basicamente o que lastIndexOf faz de qualquer maneira; por que reinventar a roda?
Michael Myers

Por diversão e para ser um pouco descritivo. só isso. (e eu esqueci lastIndexOf quando eu estava escrevendo este)
FMSF

0

Tendo em mente os cenários em que não há extensão de arquivo ou há mais de uma extensão de arquivo

exemplo Nome do arquivo: arquivo | arquivo.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();
}

Isso produzirá exemplo para img e 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;
}

Isso transformará "a.jpg.jpg" em "a" em vez de (correto) "a.jpg". Que finalidade serve para o file.length() > 0cheque?
Klaus Gütter 12/01/19

A questão principal era "como remover a extensão?", Então sim, sua transformação "a.txt.zip" para "a" e ".htaccess" para o vazio. Essa função funciona com Strings, portanto, os nomes dos arquivos não podem ser nulos, mas ainda podem ter um comprimento 0, verificar mais rapidamente se vale a pena antes de analisar os símbolos. Saudações.
Alexey
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.