[英]Remove filename extension in Java
(不包括任何外部庫。)
在不假設文件名的情況下,刪除Java中文件擴展名的最有效方法是什么?
一些例子和預期結果:
(或者應該隱藏最后一個?)
編輯 :原始問題假設輸入是文件名(不是文件路徑)。 由於一些答案是在討論文件路徑,因此這些函數也適用於以下情況:
Sylvain M的答案很好地處理了這個特例。
使用apache中的常用io http://commons.apache.org/io/
public static String removeExtension(String filename)
僅供參考,源代碼在這里:
Arg,我剛試了一下......
System.out.println(FilenameUtils.getExtension(".polop")); // polop
System.out.println(FilenameUtils.removeExtension(".polop")); // empty string
所以,這個解決方案似乎不是很好......即使使用常見的io,你也必須使用removeExtension()getExtension()indexOfExtension()......
我將要使用lastIndexOf
-index的兩個arg版本來刪除一些特殊情況檢查代碼,並希望使意圖更具可讀性。 感謝Justin'jinguy'Nelson提供此方法的基礎:
public static String removeExtention(String filePath) {
// These first few lines the same as Justin's
File f = new File(filePath);
// if it's a directory, don't remove the extention
if (f.isDirectory()) return filePath;
String name = f.getName();
// Now we know it's a file - don't need to do any special hidden
// checking or contains() checking because of:
final int lastPeriodPos = name.lastIndexOf('.');
if (lastPeriodPos <= 0)
{
// No period after first character - return name as it was passed in
return filePath;
}
else
{
// Remove the last period and everything after it
File renamed = new File(f.getParent(), name.substring(0, lastPeriodPos));
return renamed.getPath();
}
}
對我來說,這比特殊外殼隱藏文件和不包含點的文件更清晰。 它也更清楚我理解你的規范; 類似於“刪除最后一個點及其后的所有內容,假設它存在且不是文件名的第一個字符”。
請注意,此示例還將字符串視為輸入和輸出。 由於大部分抽象都需要File
對象,因此如果那些是輸入和輸出,那么它將更加清晰。
這將采用文件路徑,然后返回沒有擴展名的文件的新名稱。
public static String removeExtention(String filePath) {
File f = new File(filePath);
// if it's a directory, don't remove the extention
if (fisDirectory()) return f.getName();
String name = f.getName();
// if it is a hidden file
if (name.startsWith(".")) {
// if there is no extn, do not rmove one...
if (name.lastIndexOf('.') == name.indexOf('.')) return name;
}
// if there is no extention, don't do anything
if (!name.contains(".") return name;
// Otherwise, remove the last 'extension type thing'
return name.substring(0, name.lastIndexOf('.'))
}
人們應該注意到這是寫在我的上網本上,在微小的SO編輯器框中。 此代碼不適用於生產。 它只是服務器作為我如何從文件名中刪除擴展名的良好的第一次嘗試示例。
假設您有一個有效的文件名,這實際上非常簡單。
在Windows文件名中,點字符僅用於指定擴展名。 所以剝掉點和后面的任何東西。
在類似unix的文件名中,如果點在最后一個分隔符('/')之后並且在它和最后一個分隔符之間至少有一個字符(並且不是第一個字符,如果沒有分隔符),則點表示擴展名。 找到最后一個點,查看它是否滿足條件,並刪除它和任何尾隨字符(如果有)。
在執行此操作之前驗證文件名非常重要,因為此算法對invlaid文件名可能會執行一些意外操作並生成有效的文件名。 因此在Windows中,您可能需要檢查點后面沒有反斜杠或冒號。
如果你不知道你正在處理什么樣的文件名,那么像Unix一樣對待它們將會讓你大部分時間。
int p=name.lastIndexOf('.');
if (p>0)
name=name.substring(0,p);
我說“p> 0”而不是“p> = 0”,因為如果第一個字符是句號,我們可能不想刪除整個名稱,就像你的“.hidden”示例一樣。
您是否想要實際更新磁盤上的文件名,或者您是在談論內部操作它?
與可以想到的最簡單的方法相比,這些東西的正則表達式“足夠快”但效率不高:從末尾掃描字符串並在第一個點(不包括)處截斷它。 在Java中,您可以使用lastIndexOf和substring來僅獲取您感興趣的部分。初始點應視為特殊情況,如果最后一次出現“。”。 在開頭,應該返回整個字符串。
我知道一個正則表達式,但在Java中,我必須編寫10行代碼來進行簡單的正則表達式替換嗎?
有和沒有殺死隱藏文件:
^(.*)\..*$
^(..*)\..*$
使用新的Remover()。remove(String),
jdb@Vigor14:/tmp/stackoverflow> javac Remover.java && java Remover
folder > folder
hello.txt > hello
read.me > read
hello.bkp.txt > hello.bkp
weird..name > weird.
.hidden > .hidden
Remover.java,
import java.util.*;
public class Remover {
public static void main(String [] args){
Map<String, String> tests = new LinkedHashMap<String, String>();
tests.put("folder", "folder");
tests.put("hello.txt", "hello");
tests.put("read.me", "read");
tests.put("hello.bkp.txt", "hello.bkp");
tests.put("weird..name", "weird.");
tests.put(".hidden", ".hidden");
Remover r = new Remover();
for(String in: tests.keySet()){
String actual = r.remove(in);
log(in+" > " +actual);
String expected = tests.get(in);
if(!expected.equals(actual)){
throw new RuntimeException();
}
}
}
private static void log(String s){
System.out.println(s);
}
public String remove(String in){
if(in == null) {
return null;
}
int p = in.lastIndexOf(".");
if(p <= 0){
return in;
}
return in.substring(0, p);
}
}
filename.replace("$(.+)\.\\w+", "\1");
應重寫上面的remove()
函數以支持LOST.DIR/myfile.txt
等LOST.DIR/myfile.txt
public static String removeExtension( String in )
{
int p = in.lastIndexOf(".");
if ( p < 0 )
return in;
int d = in.lastIndexOf( File.separator );
if ( d < 0 && p == 0 )
return in;
if ( d >= 0 && d > p )
return in;
return in.substring( 0, p );
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.