Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP regular expression to match a filepath

Can someone please help me with this preg_match

if (preg_match('~[^A-Za-z0-9_\./\]~', $filepath))
    // Show Error message.

I need to match a possible filepath. So I need to check for double slashes, etc. Valid file path strings should look like this only:

mydir/aFile.php

or

mydir/another_dir/anyfile.js

So a slash at the beginning of this string should be checked also. Please help.

Thanks :)

EDIT: Also, guys, this path is being read from within a text file. It is not a filepath on the system. So hopefully it should be able to support all systems in this case.

RE-EDIT: Sorry, but the string can also look like this too: myfile.php, or myfile.js, or myfile.anything

How do I allow strings like this as well?? I apologize for not being too specific on this before...

like image 700
SoLoGHoST Avatar asked May 03 '10 06:05

SoLoGHoST


People also ask

How do I match a character in PHP?

preg_match() in PHP – this function is used to perform pattern matching in PHP on a string. It returns true if a match is found and false if a match is not found. preg_replace() in PHP – this function is used to perform a pattern match on a string and then replace the match with the specified text.

How do I match a pattern in regex?

To match a character having special meaning in regex, you need to use a escape sequence prefix with a backslash ( \ ). E.g., \. matches "." ; regex \+ matches "+" ; and regex \( matches "(" . You also need to use regex \\ to match "\" (back-slash).

How do you check if a string matches a regex in PHP?

In PHP, you can use the preg_match() function to test whether a regular expression matches a specific string. Note that this function stops after the first match, so this is best suited for testing a regular expression more than extracting data.


2 Answers

Please notice that there are many types of possible file paths. For example:

  • "./"
  • "../"
  • "........" (yes this can be a file's name)
  • "file/file.txt"
  • "file/file"
  • "file.txt"
  • "file/.././/file/file/file"
  • "/file/.././/file/file/.file" (UNIX)
  • "C:\Windows\" (Windows)
  • "C:\Windows\asd/asd" (Windows, php accepts this)
  • "file/.././/file/file/file!@#$"
  • "file/.././/file/file/file!@#.php.php.php.pdf.php"

All these file paths are valid. I can't think of a simple regex that can make it perfect.

Let's assume it's just a UNIX path for now, this is what I think should work for most cases:

preg_match('/^[^*?"<>|:]*$/',$path)

It checks all string for ^, *, ?, ", <, >, |, :(remove this for windows). These are all character that windows does not allow for file name, along with / and .

If it's windows, you should replace the path's \ with / and then explode it and check if it's absolute. Here is one example that working in both unix and windows.

function is_filepath($path)
{
    $path = trim($path);
    if(preg_match('/^[^*?"<>|:]*$/',$path)) return true; // good to go

    if(!defined('WINDOWS_SERVER'))
    {
        $tmp = dirname(__FILE__);
        if (strpos($tmp, '/', 0)!==false) define('WINDOWS_SERVER', false);
        else define('WINDOWS_SERVER', true);
    }
    /*first, we need to check if the system is windows*/
    if(WINDOWS_SERVER)
    {
        if(strpos($path, ":") == 1 && preg_match('/[a-zA-Z]/', $path[0])) // check if it's something like C:\
        {
            $tmp = substr($path,2);
            $bool = preg_match('/^[^*?"<>|:]*$/',$tmp);
            return ($bool == 1); // so that it will return only true and false
        }
        return false;
    }
    //else // else is not needed
         return false; // that t
}
like image 61
Mo Lam Avatar answered Sep 18 '22 11:09

Mo Lam


You can do:

if(preg_match('#^(\w+/){1,2}\w+\.\w+$#',$path)) {
        // valid path.
}else{
        // invalid path
}
like image 22
codaddict Avatar answered Sep 18 '22 11:09

codaddict