¿Cómo recorto una extensión de archivo de una cadena en Java?


176

¿Cuál es la forma más eficiente de recortar el sufijo en Java, así:

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

2
código eficiente, es lo que quieres decir, espero, no en cuanto a CPU
mkoryak

3
No preguntaba cómo hacerlo, preguntaba cuál era la forma más eficiente. Vine aquí buscando lo mismo.
Edward Falk

Respuestas:


285

Este es el tipo de código que no deberíamos estar haciendo nosotros mismos. Usa bibliotecas para las cosas mundanas, guarda tu cerebro para las cosas difíciles.

En este caso, recomiendo usar FilenameUtils.removeExtension () de Apache Commons IO


77
Absolutamente golpear.
Joshua Pinter

66
Para el 95% de los proyectos, esta debería ser la respuesta aceptada. ¡Reescribir código como este es la causa de muchos dolores de cabeza!
Carsten Hoffmann

1
Simplemente agregue la siguiente línea en gradle para agregar la dependencia: - compile 'commons-io: commons-io: 2.6'
Deepak Sharma

ejemplo por favor.
John Ktejik

8
Si ya tiene Apache Commons I / O en su proyecto, está bien. Pero si esto es todo lo que necesita, está agregando (al menos) 2.5 MB de peso muerto a su proyecto para algo que se puede hacer fácilmente con una sola línea.
foo

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

8
Esto debe asignarse a una nueva variable ya que str no se modifica.
Nathan Feger

51
Maneje con cuidado: le lanzará una Excepción si el nombre del archivo no tiene sufijo.
Andreas Dolk

24
¿Qué pasa con archive.tar.bz2?
Antonio

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

66
if (str! = nulo && str.contains (".")) str.substring (0, str.lastIndexOf ('.')). FilenameUtils es otra dependencia, y no siempre está disponible
ocramot

88

Como usar el String.substringy String.lastIndexen un one-liner es bueno, hay algunos problemas en términos de poder hacer frente a ciertas rutas de archivo.

Tome por ejemplo la siguiente ruta:

a.b/c

Usar el one-liner dará como resultado:

a

Eso es incorrecto

El resultado debería haber sido c, pero dado que el archivo carecía de una extensión, pero la ruta tenía un directorio con un .nombre, el método de una línea fue engañado para que diera parte de la ruta como nombre de archivo, lo cual no es correcto.

Necesidad de cheques

Inspirado por la respuesta de skaffman , eché un vistazo al FilenameUtils.removeExtensionmétodo de Apache Commons IO .

Para recrear su comportamiento, escribí algunas pruebas que el nuevo método debería cumplir, que son las siguientes:

Nombre de archivo de ruta
-------------- --------
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

(Y eso es todo lo que he verificado, probablemente haya otras comprobaciones que deberían estar en su lugar que he pasado por alto).

La implementación

La siguiente es mi implementación para el 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);
}

Ejecutar este removeExtensionmétodo con las pruebas anteriores produce los resultados enumerados anteriormente.

El método fue probado con el siguiente código. Como esto se ejecutó en Windows, el separador de ruta es un elemento \que debe escaparse con un \cuando se usa como parte de un 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"));

Los resultados fueron:

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

Los resultados son los resultados deseados descritos en la prueba que el método debe cumplir.


44
Gran respuesta. ¿Hay alguna razón particular por la que usas System.getProperty("file.separator")y no solo File.separator?
halirutan

2
Una advertencia: esta solución también elimina la ruta anterior, no solo la extensión, a diferencia del método Apache Commons IO.
DHa

3
Al parecer, esta fallará para el/path/to/.htaccess
Kuzeko

17

Por cierto, en mi caso, cuando quería una solución rápida para eliminar una extensión específica, esto es aproximadamente lo que hice:

  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('.'));

44
No, puede haber más de un '.'; quieres lastIndexOf ('.')
Adam Jaskiewicz

-1 por no usar el método que pensé que estabas usando. Eso es ahora un total de +0 de mi parte. ¡Cámbialo 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);
}

¿Es esta una pregunta con trampa? :pags

No puedo pensar en un cajero automático más rápido.



6

puedes probar esta función, muy básica

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

5

He encontrado la respuesta de coolbird particularmente útil.

Pero cambié las últimas declaraciones de resultados a:

if (extensionIndex == -1)
  return s;

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

ya que quería que se devolviera el nombre completo de la ruta.

Entonces "C: \ Users \ mroh004.COM \ Documents \ Test \ Test.xml" se convierte en 
   "C: \ Users \ mroh004.COM \ Documents \ Test \ Test" y no
   "Prueba"

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

3
Frente a lo que se pidió y no hay necesidad de pasar la longitud, solo use una subcadena arg

4

Usa una expresión regular. Este reemplaza el último punto, y todo lo que sigue.

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

También puede crear un objeto Patrón si desea precompilar la expresión regular.


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

Necesita dividirse "\\."como "." Es especial para expresiones regulares.
Brújula

1

crear un nuevo archivo con ruta de imagen de cadena

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 versión 2.4 da la siguiente respuesta

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

Me gustaría hacer esto:

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

Comenzando hasta el final hasta el '.' luego llame a la subcadena.

Editar: Puede que no sea un golf pero es efectivo :)


77
Eso es básicamente lo que lastIndexOf hace de todos modos; ¿Por qué reinventar la rueda?
Michael Myers

Por diversión y para ser un poco descriptivo. solo eso. (y olvidé lastIndexOf cuando estaba escribiendo esto)
fmsf

0

Teniendo en cuenta los escenarios donde no hay extensión de archivo o hay más de una extensión de archivo

ejemplo Nombre de archivo: archivo | 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();
}

Esto generará ejemplos 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;
}

Esto transformará "a.jpg.jpg" en "a" en lugar del (correcto) "a.jpg". ¿Para qué sirve el file.length() > 0cheque?
Klaus Gütter

La pregunta principal era "¿cómo eliminar la extensión?", Así que sí, transforma "a.txt.zip" en "a" y ".htaccess" en el vacío. Esta función funciona con cadenas, por lo que los nombres de los archivos no pueden ser nulos pero aún pueden tener una longitud de 0, verifique más rápidamente si vale la pena antes de analizar los símbolos. Saludos.
Alexey
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.