Regular Expression for File Extension

Nov 10, 2008 | Tags: Regex, PHP | del.icio.us del.icio.us | digg Digg

Getting file extension is not as easy as it looks. This is because there is no strict format for file extensions. Consider the following file names:

test.jpg
another image.jpeg
PHP Tutorial from Nashruddin.pdf
unusual.name.for.a.file.extension
my favorite, music.mp3

You cannot get the extension with substr($filename, -n), for example. To obtain the extension from filenames above, you have to use regular expression. See the following example.

Listing 1: get-fileext.php

  1. <?php
  2. $filenames = array(
  3.     'test.jpg',
  4.     'longfilename.html',
  5.     'PHP Tutorial from Nashruddin.pdf',
  6.     'unusual.name.for.a.file.extension',
  7.     'another, weird, file.jpeg',
  8.     'my favorite song.mp3'
  9. );
  10.  
  11. foreach ($filenames as $filename) {
  12.     preg_match("/\.([^\.]+)$/", $filename, $matches);    
  13.     print $matches[1] . '<br>';
  14. }
  15.  
  16. /* will print:
  17. jpg
  18. html
  19. pdf
  20. extension
  21. jpeg
  22. mp3 */
  23. ?>
  24.  

Related Articles

Recommended Books

11 Comments

Flashparry on Jul 27, 2008:

Thanks - works a treat

Jakub Neubauer on Sep 5, 2008:

But with file without extension you have problem. I found this regexp (for Java, but I hope it can be converted to PHP regexp engine):
(.+?)(\.([^\.]*))?$
In group 1 will be the name, in group 3 the extension.

Nash on Nov 9, 2008:

I don't think it would be a problem. If the file has no extension, it simply returns empty string. However, it is a good idea to get the filename too.

<?php
$filename = 'regex-for-file-extension.html';
preg_match('/^(.+)(\.([^\.]*))?$/', $filename, $matches);

echo "name: $matches[1]<br />";
echo "ext: $matches[3]<br />";

/*
will print:

name: regex-for-file-extension
ext: html
*/

?>
Thanks for the regex.

Elvita on Dec 15, 2008:

Hi Nash,

The regex is ok. but what if the filename comes with full path. eg: /home/elvita/docs/my_paper.pdf
how to extract the filename (my_paper.pdf). thanks

Nash on Dec 15, 2008:

Hi Elvita,
You don't need to use regular expression for that. simply use basename().

<?php
$file = '/home/elvita/docs/my_paper.pdf';
echo basename($file);
/* will print: my_paper.pdf */
?>

Ning on Mar 31, 2009:

This regexp works for most of the cases, but for files with multi-extensions you will lose the accurate extension. For instance a mybackup.tar.gz file with the above regexp will return as .gz extension. If you later alter the name of the file and append the extension become something like backup2009.gz. Keep in mind that a .tar.gz file is NOT the same as a .gz file!!

Nash on Mar 31, 2009:

Hey, you're right! I never thought about multi-extensions files.
So that would be the limitation of this regex.

Salman on Jun 29, 2009:

@ Ning:

IMHO, the fragment after the last "." should be considered as the file extension. Considering the fragment after the first "." as the file name extension would be wrong in many situations. Consider this filename: Joomla_1.5.11-Stable-Full_Package.zip

In this example, the extension is ".zip", not ".5.11-Stable-Full_Package.zip"

Apart from this, in the above example you might want to add "if" conditions and "isset" to check that (1) preg_match succeeds (2) an extension is found. Otherwise you might see php notices for filenames that do not have contain a "." and hence have no extension.

J on Jul 4, 2009:

I've been using:

function getFileExtension($filename){
  return str_replace('.', '', substr($filename, strrpos($filename, '.')));
}

function getFileExtensionCaseInsensitive($filename){
  return strtolower(substr(strrchr($filename, "."), 1));
}

carlo on Sep 13, 2009:

what about this?:

<?php
// get_extension.php
$filenames = array(
  'test.jpg',
  'longfilename.html',
  'PHP Tutorial from Nashruddin.pdf',
  'unusual.name.for.a.file.extension',
  'another, weird, file.jpeg',
  'my favorite song.mp3'
);

foreach($filenames as $f) {
  $lastdot = strrpos($f, '.');
  if (!($lastdot === FALSE))
    $ext[] = substr($f, $lastdot + 1);
}

echo "<pre>";
print_r($ext);
echo "</pre>";
?>

Emanuel on Apr 8, 2011:

I think this is faster:
$x = explode('.', $filename);
$ext = '.'.end($x);
But also doesn't work for tar.gz

Leave a comment

Name (required)
Email (will not be published) (required)
Website

Characters left = 1000