說我有這樣的事情:常規是否有一個簡單的方法來獲得不帶擴展名的文件名?
這將打印在test
目錄中所有文件的完整文件名。有沒有Groovy的方式來獲得沒有任何擴展名的文件名? (還是我回到了正則表達式的土地?)
說我有這樣的事情:常規是否有一個簡單的方法來獲得不帶擴展名的文件名?
這將打印在test
目錄中所有文件的完整文件名。有沒有Groovy的方式來獲得沒有任何擴展名的文件名? (還是我回到了正則表達式的土地?)
如你預期也許並不容易,但工作:
new File("test").eachFile {
println it.name.lastIndexOf('.') >= 0 ?
it.name[0 .. it.name.lastIndexOf('.')-1] :
it.name
}
您可以使用正則表達式更好。 像下面的函數會做的伎倆:
def getExtensionFromFilename(filename) {
def returned_value = ""
m = (filename =~ /(\.[^\.]*)$/)
if (m.size()>0) returned_value = ((m[0][0].size()>0) ? m[0][0].substring(1).trim().toLowerCase() : "");
return returned_value
}
我相信grooviest方法是:
file.name.lastIndexOf('.').with {it != -1 ? file.name[0..<it] : file.name}
或用一個簡單的正則表達式:
file.name.replaceFirst(~/\.[^\.]+$/, '')
也有一個Apache commons-io java lib用於那種目的,如果你使用maven,你可以很容易地依賴它:
org.apache.commons.io.FilenameUtils.getBaseName(file.name)
new File("test").eachFile() { file->
println file.getName().split("\\.")[0]
}
這非常適用於像文件名: FOO,foo.bar
但是,如果你有一個文件foo.bar.jar,那麼上面的代碼打印出:FOO 如果你想讓它打印出foo.bar,然後下面的代碼實現了。
new File("test").eachFile() { file->
def names = (file.name.split("\\.")
def name = names.size() > 1 ? (names - names[-1]).join('.') : names[0]
println name
}
正如註釋所提到的,其中,文件名結束&的擴展開始視情況而定。在我情況,我需要得到基本名稱(文件沒有路徑,和無擴展名)以下類型的文件:{foo.zip
,bar/foo.tgz
,foo.tar.gz
} =>所有需要出示「foo
」作爲文件名SANS延期。 (大多數解決方案,給出foo.tar.gz
將產生foo.tar
。)
下面是一個(顯而易見的)解決方案,它會給你所有的東西,直到第一個「。」;可選地,您可以將整個擴展名作爲單個餘數(將文件名拆分爲2
部分)。 (注:雖然無關手頭的任務,我也去掉路徑中,通過調用file.name
。)
file=new File("temp/foo.tar.gz")
file.name.split("\\.", 2)[0] // => return "foo" at [0], and "tar.gz" at [1]
我不知道爲什麼我沒有看到mauro的答案,直到發佈後。這應該是一個評論,因爲它幾乎相同,但沒有forEach/closure。我現在就離開這個了,因爲如果不熟悉'{file - > yada yada}'語法(這當然是原始問題,但是在其他方面與問題無關),閱讀起來會更簡單。 – michael 2014-04-16 01:10:39
的FilenameUtils類,它是Apache公地IO包的一部分,有一個強大的解。用法示例:
import org.apache.commons.io.FilenameUtils
String filename = '/tmp/hello-world.txt'
def fileWithoutExt = FilenameUtils.removeExtension(filename)
這不是常規的方式,但如果你需要支持大量的邊緣情況可能會有所幫助。
注意
import java.io.File;
def fileNames = [ "https://stackoverflow.com/a/b.c/first.txt",
"/b/c/second",
"c:\\a\\b.c\\third...",
"c:\\a\b\\c\\.text"
]
def fileSeparator = "";
fileNames.each {
// You can keep the below code outside of this loop. Since my example
// contains both windows and unix file structure, I am doing this inside the loop.
fileSeparator= "\\" + File.separator;
if (!it.contains(File.separator)) {
fileSeparator = "\\/"
}
println "File extension is : ${it.find(/((?<=\.)[^\.${fileSeparator}]+)$/)}"
it = it.replaceAll(/(\.([^\.${fileSeparator}]+)?)$/,"")
println "Filename is ${it}"
}
一些下面的解決方案(除了使用Apache庫中的一個),這個例子不起作用 - C:/test.me/firstfile
如果我嘗試找到上面的條目延期,我會得到「.ME/firstfile」 -
:(更好的方法將是如果存在找到文件分割符的最後出現,然後查找文件名或擴展。
注意: (有一個小技巧發生在下面。對於Windows,文件分隔符是\。但是這是正則表達式中的一個特殊字符,所以當我們在正則表達式中使用包含File.separator的變量時,我必須將其轉義。這就是爲什麼我這樣做:
def fileSeparator= "\\" + File.separator;
希望這是有道理的:)
嘗試了這一點:
import java.io.File;
String strFilename = "C:\\first.1\\second.txt";
// Few other flavors
// strFilename = "/dd/dddd/2.dd/dio/dkljlds.dd"
def fileSeparator= "\\" + File.separator;
if (!strFilename.contains(File.separator)) {
fileSeparator = "\\/"
}
def fileExtension = "";
(strFilename =~ /((?<=\.)[^\.${fileSeparator}]+)$/).each { match, extension -> fileExtension = extension }
println "Extension is:$fileExtension"
最徹底的方法。
String fileWithoutExt = file.name.take(file.name.lastIndexOf('.'))
簡單的方法是:
'file.name.with.dots.tgz' - ~/\.\w+$/
結果是:
file.name.with.dots
// Create an instance of a file (note the path is several levels deep)
File file = new File('/tmp/whatever/certificate.crt')
// To get the single fileName without the path (but with EXTENSION! so not answering the question of the author. Sorry for that...)
String fileName = file.parentFile.toURI().relativize(file.toURI()).getPath()
我不明白... – 2017-04-06 12:11:51
我也沒有:)我明顯提供了一個如何獲取沒有路徑的文件名,但WITH擴展名的例子。所以我沒有回答作者的問題。 – Marco 2017-04-13 15:53:35
有時文件不具有擴展名,但確實有他們'.'。 – 2009-10-15 10:03:38