Don't write your own code for this, take advantage of Ruby's own built-in code:
File.extname("test.rb") # => ".rb"
File.extname("a/b/d/test.rb") # => ".rb"
File.extname(".a/b/d/test.rb") # => ".rb"
File.extname("foo.") # => "."
File.extname("test") # => ""
File.extname(".profile") # => ""
File.extname(".profile.sh") # => ".sh"
You're missing some cases. Compare the above to the output of your attempts:
fnames = %w[
test.rb
a/b/d/test.rb
.a/b/d/test.rb
foo.
test
.profile
.profile.sh
]
fnames.map { |fn|
fn.match(/\.(\w*)/).to_s
}
# => [".rb", ".rb", ".a", ".", "", ".profile", ".profile"]
fnames.map { |fn|
fn.scan(/\.(\w*)/).to_s
}
# => ["[[\"rb\"]]",
# "[[\"rb\"]]",
# "[[\"a\"], [\"rb\"]]",
# "[[\"\"]]",
# "[]",
# "[[\"profile\"]]",
# "[[\"profile\"], [\"sh\"]]"]
The documentation for File.extname says:
Returns the extension (the portion of file name in path starting from the last period).
If path is a dotfile, or starts with a period, then the starting dot is not dealt with the start of the extension.
An empty string will also be returned when the period is the last character in path.
On Windows, trailing dots are truncated.
The File class has many more useful methods to pick apart filenames. There's also the Pathname class which is very useful for similar things.