groovy 是否有一种简单的方法来获取不带扩展名的文件名?

发布于 2024-08-08 00:20:38 字数 207 浏览 6 评论 0原文

假设我有这样的内容:

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

这将打印 test 目录中每个文件的完整文件名。有没有一种 Groovy 方法可以获取不带任何扩展名的文件名? (或者我又回到了正则表达式领域?)

Say I have something like this:

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

This prints the full filename of every file in the test directory. Is there a Groovy way to get the filename without any extension? (Or am I back in regex land?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

绝情姑娘 2024-08-15 00:20:38

我相信最好的方法是:

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)

I believe the grooviest way would be:

file.name.lastIndexOf('.').with {it != -1 ? file.name[0..<it] : file.name}

or with a simple regexp:

file.name.replaceFirst(~/\.[^\.]+$/, '')

also there's an apache commons-io java lib for that kinda purposes, which you could easily depend on if you use maven:

org.apache.commons.io.FilenameUtils.getBaseName(file.name)
雨落□心尘 2024-08-15 00:20:38

最干净的方式。

String fileWithoutExt = file.name.take(file.name.lastIndexOf('.'))

The cleanest way.

String fileWithoutExt = file.name.take(file.name.lastIndexOf('.'))

一城柳絮吹成雪 2024-08-15 00:20:38

最简单的方法是:

'file.name.with.dots.tgz' - ~/\.\w+$/​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

结果是:

file.name.with.dots

Simplest way is:

'file.name.with.dots.tgz' - ~/\.\w+$/​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

Result is:

file.name.with.dots
埋葬我深情 2024-08-15 00:20:38
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
}
new File("test").eachFile() { file->  
    println file.getName().split("\\.")[0]
}

This works well for file names like:
foo, foo.bar

But if you have a file foo.bar.jar, then the above code prints out: foo
If you want it to print out foo.bar instead, then the following code achieves that.

new File("test").eachFile() { file->  
    def names = (file.name.split("\\.")
    def name = names.size() > 1 ? (names - names[-1]).join('.') : names[0]
    println name
}
久伴你 2024-08-15 00:20:38

FilenameUtils 类是 apache commons io 包的一部分,有一个强大的解决方案。用法示例:

import org.apache.commons.io.FilenameUtils

String filename = '/tmp/hello-world.txt'
def fileWithoutExt = FilenameUtils.removeExtension(filename)

这不是常规方法,但如果您需要支持大量边缘情况,这可能会有所帮助。

The FilenameUtils class, which is part of the apache commons io package, has a robust solution. Example usage:

import org.apache.commons.io.FilenameUtils

String filename = '/tmp/hello-world.txt'
def fileWithoutExt = FilenameUtils.removeExtension(filename)

This isn't the groovy way, but might be helpful if you need to support lots of edge cases.

戴着白色围巾的女孩 2024-08-15 00:20:38

也许不像你想象的那么容易,但工作:

new File("test").eachFile { 
  println it.name.lastIndexOf('.') >= 0 ? 
     it.name[0 .. it.name.lastIndexOf('.')-1] : 
     it.name 
  }

Maybe not as easy as you expected but working:

new File("test").eachFile { 
  println it.name.lastIndexOf('.') >= 0 ? 
     it.name[0 .. it.name.lastIndexOf('.')-1] : 
     it.name 
  }
三生路 2024-08-15 00:20:38

正如评论中提到的,文件名结尾 &延期开始取决于具体情况。在的情况下,我需要获取以下类型文件的基本名称(没有路径的文件,没有扩展名):{ foo.zip, bar/foo.tgz, foo.tar.gz } =>;都需要生成“foo”作为没有扩展名的文件名。 (大多数解决方案,给定 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]

As mentioned in comments, where a filename ends & an extension begins depends on the situation. In my situation, I needed to get the basename (file without path, and without extension) of the following types of files: { foo.zip, bar/foo.tgz, foo.tar.gz } => all need to produce "foo" as the filename sans extension. (Most solutions, given foo.tar.gz would produce foo.tar.)

Here's one (obvious) solution that will give you everything up to the first "."; optionally, you can get the entire extension either in pieces or (in this case) as a single remainder (splitting the filename into 2 parts). (Note: although unrelated to the task at hand, I'm also removing the path as well, by calling file.name.)

file=new File("temp/foo.tar.gz")
file.name.split("\\.", 2)[0]    // => return "foo" at [0], and "tar.gz" at [1]
深空失忆 2024-08-15 00:20:38

您可以更好地使用正则表达式。
像下面这样的函数就可以解决这个问题:

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
}

You can use regular expressions better.
A function like the following would do the trick:

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
}
白昼 2024-08-15 00:20:38

注意

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

如果我尝试查找上述条目的扩展名,我会get ".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"

Note

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}" 
}

Some of the below solutions (except the one using apache library) doesn't work for this example - c:/test.me/firstfile

If I try to find an extension for above entry, I will get ".me/firstfile" - :(

Better approach will be to find the last occurrence of File.separator if present and then look for filename or extension.

Note:
(There is a little trick happens below. For Windows, the file separator is \. But this is a special character in regular expression and so when we use a variable containing the File.separator in the regular expression, I have to escape it. That is why I do this:

def fileSeparator= "\\" + File.separator;

Hope it makes sense :)

Try this out:

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"
余生再见 2024-08-15 00:20:38
// 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()
// 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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文