Is there a regular expression in Perl to find a file's extension? For example, if I have "test.exe
", how would I get the ".exe
"?
Asked
Active
Viewed 4.8k times
22
-
@Ether..I think its a great question. I have been into Perl on and off for more than a decade and there are times when I just want some quick reference. – aloha Jan 13 '12 at 11:35
5 Answers
47
my $file = "test.exe";
# Match a dot, followed by any number of non-dots until the
# end of the line.
my ($ext) = $file =~ /(\.[^.]+)$/;
print "$ext\n";

Gavin Brock
- 5,027
- 1
- 30
- 33
-
This is perfect. Is there a regex command to separate the two in one shot? i.e.'happy.jpg' and you would be left with two variable, one equal to 'happy' and one '.jpeg – Daniel Kaplan Jul 11 '19 at 05:49
-
When the filename doesn't have an extension, you will get a `Use of uninitialized value $ext` error on the print statement. – pacoverflow Apr 01 '23 at 21:50
14
use File::Basename
use File::Basename;
($name,$path,$suffix) = fileparse("test.exe.bat",qr"\..[^.]*$");
print $suffix;

pevik
- 4,523
- 3
- 33
- 44

ghostdog74
- 327,991
- 56
- 259
- 343
-
3I've never thought that File::Basename was any good for this job considering that you have to supply the pattern that you could have used with the match operator to get the same thing done. – brian d foy Mar 18 '10 at 03:58
-
2if its just to get extension, a normal regex would suffice. But File::Basename parses the rest of the path as well. If OP needs to get them besides extension need, File::Basename comes in handy. – ghostdog74 Mar 18 '10 at 04:39
-
Warning: I had files which users named as `filename..doc` and the regep for suffix above will return `..doc` as the extension. Prefer the one in @toolic reply (or the Perl Docs for File:Basename) if going in this direction. – Jacob Zwiers Oct 10 '13 at 16:17
4
Here it is a regex to match pattern n-level extension file (e.g. .tar.gz or .tar.bz2).
((\.[^.\s]+)+)$
Example:
#!/usr/bin/perl
my $file1 = "filename.tar.gz.bak";
my ($ext1) = $file1 =~ /((\.[^.\s]+)+)$/;
my $file2 = "filename.exe";
my ($ext2) = $file2 =~ /((\.[^.\s]+)+)$/;
my $file3 = "filename. exe";
my ($ext3) = $file3 =~ /((\.[^.\s]+)+)$/;
my $file4 = "filename.............doc";
my ($ext4) = $file4 =~ /((\.[^.\s]+)+)$/;
print "1) $ext1\n"; # prints "1) .tar.gz.bak"
print "2) $ext2\n"; # prints "2) .exe"
print "3) $ext3\n"; # prints "3) "
print "4) $ext4\n"; # prints "4) .doc"

Filippo Lauria
- 1,965
- 14
- 20
4
\.[^\.]*$
This would give you everything after the last dot (including the dot itself) until the end of the string.

Dean Harding
- 71,468
- 13
- 145
- 180
3
You could use File::Basename to extract an arbitrary file extension:
use strict;
use warnings;
use File::Basename;
my $ext = (fileparse("/foo/bar/baz.exe", qr/\.[^.]*/))[2];
print "$ext";

toolic
- 57,801
- 17
- 75
- 117