22

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

toolic
  • 57,801
  • 17
  • 75
  • 117
Zerobu
  • 2,561
  • 7
  • 25
  • 32
  • @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 Answers5

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
  • 3
    I'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
  • 2
    if 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