Java의 문자열에서 파일 확장자를 자르려면 어떻게해야합니까?


177

Java에서 접미사를 자르는 가장 효율적인 방법은 다음과 같습니다.

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

2
현명한 효율적인 코드, 당신은 현명, 내가 희망 CPU를하지 무슨 뜻입니다
mkoryak

3
그는 어떻게해야하는지 묻지 않고 가장 효율적인 방법을 묻고있었습니다. 나는 같은 것을 찾기 위해 여기에 왔습니다.
Edward Falk

답변:


285

이것은 우리가 직접해서는 안되는 일종의 코드입니다. 평범한 물건을 위해 라이브러리를 사용하고 어려운 물건을 위해 두뇌를 구하십시오.

이 경우 Apache Commons IO 에서 FilenameUtils.removeExtension () 을 사용하는 것이 좋습니다.


7
물론
Joshua Pinter

6
프로젝트의 95 %는 이것이 정답이어야합니다. 이와 같은 코드를 다시 작성하는 것은 많은 두통의 근본 원인입니다!
Carsten Hoffmann

1
다음 줄을 gradle에 추가하여 depedency를 추가하십시오 .- 'commons-io : commons-io : 2.6'컴파일
Deepak Sharma

예를 들어주세요.
john ktejik

8
프로젝트에 Apache Commons I / O가 이미 있다면 맞습니다. 그러나 이것으로 필요한 모든 것이 있다면, 한 줄로 쉽게 수행 할 수있는 최소한 2.5MB의 중량을 프로젝트에 추가하는 것입니다.
foo

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

8
str이 수정되지 않으므로 새 변수에 지정해야합니다.
Nathan Feger

51
주의해서 다루십시오 : 파일 이름에 접미사가 없으면 예외가 발생합니다.
Andreas Dolk

24
archive.tar.bz2는 어떻습니까?
안토니오

20
if(str.contains(".")) str.substring(0, str.lastIndexOf('.'))
니콜라스 타일러

6
if (str! = null && str. ( ".")) str.substring (0, str.lastIndexOf ( '.')). FilenameUtils 항상 사용할 또 다른 의존성, 그리고하지
ocramot

88

를 사용으로 String.substring하고 String.lastIndex한 라이너가 좋은에서 특정 파일 경로에 대처 할 수있는 측면에서 몇 가지 문제가 있습니다.

다음 경로를 예로 들어 보겠습니다.

a.b/c

하나의 라이너를 사용하면 다음과 같은 결과가 발생합니다.

a

맞습니다.

결과는 c였지만 파일의 확장자는 없었지만 경로 .에 이름 이 포함 된 디렉토리가 있으므로 one-liner 메소드가 경로의 일부를 파일 이름으로 제공하도록 속이는 것은 정확하지 않습니다.

점검 필요

skaffman의 답변 에서 영감을 받아 Apache Commons IOFilenameUtils.removeExtension방법을 살펴 보았습니다 .

동작을 재현하기 위해 새로운 방법이 수행해야 할 몇 가지 테스트를 작성했습니다.

경로 파일 이름
-------------- --------
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

(그리고 이것이 내가 확인한 전부입니다. 아마도 간과해야 할 다른 점검이있을 것입니다.)

구현

다음은 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);
}

removeExtension위의 테스트 로이 방법을 실행 하면 위에 나열된 결과가 생성됩니다.

이 방법은 다음 코드로 테스트되었습니다. 이것이 Windows에서 실행되었으므로 경로 구분 기호는 리터럴의 일부로 사용될 때 \이스케이프 처리해야합니다 .\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"));

결과는 다음과 같습니다.

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

결과는 방법이 충족해야하는 테스트에 요약 된 원하는 결과입니다.


4
좋은 대답입니다. 당신이 사용하는 이유 특정 이유가 System.getProperty("file.separator")그냥하고 File.separator?
halirutan

2
경고 :이 솔루션은 Apache Commons IO 방법과 달리 확장 기능뿐만 아니라 이전 경로도 제거합니다.
DHa

3
/path/to/.htaccess
Kuzeko

17

BTW, 제 경우에는 특정 확장을 제거하는 빠른 솔루션을 원할 때 대략 다음과 같습니다.

  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
아니요, 하나 이상의 '.'가있을 수 있습니다.; lastIndexOf ( '.')
Adam Jaskiewicz 2016 년

내가 사용하고 있다고 생각한 방법을 사용하지 않은 경우 -1입니다. 이제는 총 +0입니다. 빨리 바꾸세요! ;)
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);
}

이것은 까다로운 질문입니까? :피

나는 더 빠른 ATM을 생각할 수 없다.



6

이 기능을 매우 기본적으로 사용해 볼 수 있습니다

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

5

쿨 버드의 답변이 특히 유용하다는 것을 알았습니다 .

그러나 마지막 결과 진술을 다음과 같이 변경했습니다.

if (extensionIndex == -1)
  return s;

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

전체 경로 이름을 반환하고 싶었습니다.

따라서 "C : \ Users \ mroh004.COM \ Documents \ Test \ Test.xml"이됩니다. 
   "C : \ Users \ mroh004.COM \ Documents \ Test \ Test"가 아닌
   "테스트"

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

3
요청 된 것과 반대로 길이를 전달할 필요가 없습니다. arg 하위 문자열 하나만 사용하십시오

4

정규식을 사용하십시오. 이것은 마지막 점과 그 뒤의 모든 것을 대체합니다.

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

정규식을 미리 컴파일하려는 경우 Pattern 객체를 만들 수도 있습니다.


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

"\\.""." 으로 분할해야합니다 . 정규식에 특별합니다.
Compass

1

문자열 이미지 경로로 새 파일을 만듭니다.

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 버전 2.4는 다음과 같은 답변을 제공합니다.

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

나는 이것을 좋아할 것이다 :

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

'.'까지 끝까지 시작 그런 다음 하위 문자열을 호출하십시오.

편집 : 골프는 아니지만 효과적입니다 :)


7
이것이 기본적으로 lastIndexOf가하는 일입니다. 왜 바퀴를 재발 명합니까?
Michael Myers

재미 있고 약간 설명하기. 그냥. (그리고 이것을 쓸 때 lastIndexOf를 잊어 버렸습니다)
fmsf

0

파일 확장자가 없거나 둘 이상의 파일 확장자가있는 시나리오를 명심하십시오.

예 Filename : 파일 | 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();
}

이 뜻 출력 예를 모두 IMGimgLink


0
public static String removeExtension(String file) {
    if(file != null && file.length() > 0) {
        while(file.contains(".")) {
            file = file.substring(0, file.lastIndexOf('.'));
        }
    }
    return file;
}

그러면 (올바른) "a.jpg"대신 "a.jpg.jpg"가 "a"로 변환됩니다. file.length() > 0수표의 목적은 무엇입니까 ?
Klaus Gütter

주요 질문은 "확장자를 어떻게 제거 하는가?"였습니다. 따라서 "a.txt.zip"을 "a"로, ".htaccess"를 공허로 변환합니다. 이 함수는 문자열과 함께 작동하므로 파일 이름은 null 일 수 없지만 길이는 0 일 수 있으므로 기호를 구문 분석하기 전에 값이 더 빠른지 확인하십시오. 문안 인사.
Alexey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.