groovy有一个简单的方法来获取没有扩展名的文件名吗?

时间:2009-10-14 23:23:36

标签: java file-io groovy file-extension

说我有这样的事情:

new File("test").eachFile() { file->  
println file.getName()  
}

这将打印test目录中每个文件的完整文件名。是否有一种Groovy方式来获取没有任何扩展名的文件名? (或者我回到正义之地?)

10 个答案:

答案 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()