说我有这样的事情:
new File("test").eachFile() { file->
println file.getName()
}
这将打印test
目录中每个文件的完整文件名。是否有一种Groovy方式来获取没有任何扩展名的文件名? (或者我回到正义之地?)
答案 0 :(得分:46)
我相信最流行的方式是:
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)
答案 1 :(得分:28)
最干净的方式。
String fileWithoutExt = file.name.take(file.name.lastIndexOf('.'))
答案 2 :(得分:7)
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
}
答案 3 :(得分:4)
可能不像你预期的那样容易但是工作:
new File("test").eachFile {
println it.name.lastIndexOf('.') >= 0 ?
it.name[0 .. it.name.lastIndexOf('.')-1] :
it.name
}
答案 4 :(得分:4)
FilenameUtils类是apache commons io包的一部分,它有一个强大的解决方案。用法示例:
import org.apache.commons.io.FilenameUtils
String filename = '/tmp/hello-world.txt'
def fileWithoutExt = FilenameUtils.removeExtension(filename)
这不是常规方式,但如果您需要支持大量边缘情况,可能会有所帮助。
答案 5 :(得分:3)
最简单的方法是:
'file.name.with.dots.tgz' - ~/\.\w+$/
结果是:
file.name.with.dots
答案 6 :(得分:1)
正如评论中所提到的,文件名结尾处是&amp;延期开始取决于具体情况。在 my 的情况下,我需要获取以下类型文件的基本名称(没有路径的文件,和,不带扩展名):{foo.zip
,{{1 }},bar/foo.tgz
} =&gt;所有都需要生成“foo.tar.gz
”作为文件名sans扩展名。 (给定foo
的大多数解决方案都会产生foo.tar.gz
。)
这是一个(显而易见的)解决方案,可以为您提供第一个“。”;可选地,您可以将整个扩展分段或(在本例中)作为单个余数(将文件名拆分为foo.tar
部分)。 (注意:虽然与手头的任务无关,但我也通过调用2
来删除路径。)
file.name
答案 7 :(得分:0)
您可以更好地使用正则表达式。 像下面这样的函数可以解决这个问题:
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
}
答案 8 :(得分:0)
注意强>
import java.io.File;
def fileNames = [ "/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” - :(
更好的方法是找到最后一次出现的File.separator(如果存在),然后查找文件名或扩展名。
注意:强> (下面有一个小技巧。对于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"
答案 9 :(得分:-1)
// 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()