在Ruby中查找文件名的扩展名

119

我正在处理Rails应用程序中的文件上传部分。该应用程序根据不同类型的文件进行不同的处理。

我想要创建一个白名单,包含特定的文件扩展名,以检查上传的文件所属的位置。所有的文件名都是字符串。

我需要一种方法仅检查文件名字符串的扩展名部分。文件名都是按照“一些文件名.一些扩展名”的格式命名。

6个回答

186
irb(main):002:0> accepted_formats = [".txt", ".pdf"]
=> [".txt", ".pdf"]
irb(main):003:0> File.extname("example.pdf") # get the extension
=> ".pdf"
irb(main):004:0> accepted_formats.include? File.extname("example.pdf")
=> true
irb(main):005:0> accepted_formats.include? File.extname("example.txt")
=> true
irb(main):006:0> accepted_formats.include? File.extname("example.png")
=> false

4
"file_with_no_extension".split('.').last 怎么样? - a'r
12
很遗憾,这种方式不能用于包括 tar.gztar.bz2 等多个后缀的文件。 - KomodoDave
2
@KomodoDave 对于多周期后缀,除了启发式(因此容易出错)的扩展名数据库外,没有其他有效的解决方法。 - Ciro Santilli OurBigBook.com
5
为确保文件扩展名不全是大写字母,您可以执行File.extname("example.png").downcase命令。 - Sam Eaton

91
使用 File 类的 `extname` 方法。
File.extname("test.rb")         #=> ".rb"

你可能需要使用 basename 方法。

File.basename("/home/gumby/work/ruby.rb", ".rb")   #=> "ruby"

18

虽然是一个很老的话题,但下面是去掉扩展分隔符点和可能的尾随空格的方法:

File.extname(path).strip.downcase[1..-1]

示例:

File.extname(".test").strip.downcase[1..-1]       # => nil
File.extname(".test.").strip.downcase[1..-1]      # => nil
File.extname(".test.pdf").strip.downcase[1..-1]   # => "pdf"
File.extname(".test.pdf ").strip.downcase[1..-1]  # => "pdf"

7

我认为,如果去掉扩展名分隔符会更容易实现。

File.extname(path).delete('.')

我使用 File.extname(path).delete_prefix(".") - 我觉得它更好地传达了意图(只有前缀,只有一个),尽管据我所知没有实际区别 - File.extname("foo.bar.baz") 只会给出 ".baz" - Henrik N

1

另一种方法是使用delete_suffixdelete_prefix。在我看来,这种方法更容易阅读。

filename = 'path/to/file.ext'
file_name_only = File.basename(filename).delete_suffix(File.extname(filename))
file_ext = File.extname(filename).delete_prefix '.'
file_path = File.dirname(filename)
new_name = "#{file_path}/#{file_name_only}_blahblah.#{file_ext}"

在IRB中:
$ irb
irb(main):001:0> filename = 'path/to/file.ext'
=> "path/to/file.ext"
irb(main):002:0> file_name_only = File.basename(filename).delete_suffix(File.extname(filename))
=> "file"
irb(main):003:0> file_ext = File.extname(filename).delete_prefix '.'
=> "ext"
irb(main):004:0> file_path = File.dirname(filename)
=> "path/to"
irb(main):005:0> new_name = "#{file_path}/#{file_name_only}_blahblah.#{file_ext}"
=> "path/to/file_blahblah.ext"
irb(main):006:0>

0
这篇文章回答了我的问题,但我的用例恰好相反。我想找到没有扩展名的文件名。我使用File.basename找到了文件名,然后将File.extnamegsub组合在一起,以删除.md,如下所示:
@file = '/path/to/my-file-name.md' 
File.basename(@file).gsub(File.extname(@file),'')

# => 'my-file-name'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接