9

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...

6
  • Only the two sample paths shown by you should be matched ? Commented May 3, 2010 at 6:17
  • Any file extension should be matched. Can't have any slashes in front of the string, and can't have any slashes at the very end of the string. That's the only limit to it, and it must be characters A-Z, a-z, 0-9, or have and underscore or a dot in it. That's all. Commented May 3, 2010 at 6:19
  • What file systems should the path be valid for? Commented May 3, 2010 at 6:26
  • All, if possible. Otherwise, most. Commented May 3, 2010 at 6:27
  • @SoLoGHoST: There are tens of different file systems and all have different specification (see en.wikipedia.org/wiki/Comparison_of_file_systems). The union of these specifications is probably just [A-Z0-9]{1,8} for file names (MS-DOS does only allow 8 Byte) and a total length of 30 Bytes for the path length (Apple DOS 3.x does only allow 30 Bytes). Commented May 3, 2010 at 6:34

2 Answers 2

15

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
}
Sign up to request clarification or add additional context in comments.

1 Comment

can I concat all possible regex in one regex
9

You can do:

if(preg_match('#^(\w+/){1,2}\w+\.\w+$#',$path)) {
        // valid path.
}else{
        // invalid path
}

7 Comments

can I use this like so to only check for invalid paths only? if(!preg_match('#^(\w+/){1,2}\w+\.\w+$#',$path))
Sorry, this isn't working, I tried it, but it's going to an error message when I have this string: myfile.php
Ok, it doesn't have to have a slash in it, how do I change this to account for that as well??
preg_match('#^(\w+/){0,2}\w+\.\w+$#',$path)
webcheatsheet.com/php/regular_expressions.php - check a tutorial on regular expressions.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.