16

I want to check whether a string is a file name (name DOT ext) or not.

Name of file cannot contain / ? * : ; { } \

Could you please suggest me the regex expression to use in preg_match()?

Rob Wells
  • 36,220
  • 13
  • 81
  • 146
OrangeRind
  • 4,798
  • 13
  • 45
  • 57

5 Answers5

19

Here you go:

"[^/?*:;{}\\]+\\.[^/?*:;{}\\]+"

"One or more characters that aren't any of these ones, then a dot, then some more characters that aren't these ones."

(As long as you're sure that the dot is really required - if not, it's simply: "[^/?*:;{}\\]+"

RichieHindle
  • 272,464
  • 47
  • 358
  • 399
  • 2
    @Richie, do you really need the second backslash just before the dot separator? shouldn't it be ...}\\\]+\.[^/?.... – Rob Wells Jun 23 '09 at 12:15
  • 2
    @Rob Wells: It is necessary since PHP strings use the backslash as an escape character as well. "\\" in a PHP string is translated to "\" in the regex. That "\." is translated to "\." is a coincidence resulting from the fact that "\." has no meaning to PHP and is therefore left unchanged. Nontheless it is sloppy not to escape the backslash. – Tomalak Jun 23 '09 at 12:18
  • error coming. might be my mistake, please see I entered $page_regex = "[[^/?*:;{}\\]+\\.[^/?*:;{}\\]+"; $len = $this->REQ_URI_PATH_E_LEN; //length of $this->REQ_URI_PATH_E_LEN given below $page = $this->REQ_URI_PATH_E[$len - 1]; //holds path elements like 0=>posts, 1=>hello, 2=>newp.php for localhost/posts/hello/newp.php?id=3 if(preg_match($page_regex,$page)) echo "page"; else echo "Folder"; error is "Warning: preg_match() [function.preg-match]: No ending matching delimiter ']' found in *line*" I might be wrong with the syntax, please correct me. – OrangeRind Jun 23 '09 at 12:37
  • You have two opening brackets right at the start of the string: "[[ – RichieHindle Jun 23 '09 at 12:44
  • sorry probably typo but "[^/?*:;{}\\]+\\.[^/?*:;{}\\]+" is what i entered and it gave the error. Copied it now straight from your answer to this comment and my code as well :( – OrangeRind Jun 23 '09 at 13:17
  • Perhaps you need to escape the forward slashes: [^\/?*:;{}\\]+\\.[^\/?*:;{}\\]+ – RichieHindle Jun 23 '09 at 13:31
  • no luck. but $page_regex is showing [^\/?*:;{}\]+\.[^\/?*:;{}\]+ on echo. gawd. this regex mumbo jumbo is getting on mah nerves – OrangeRind Jun 23 '09 at 13:40
  • even [^/?*:;{}\\]+\\.[^/?*:;{}\\] doen't work. whats the + at the end for (in your answer)? – OrangeRind Jun 23 '09 at 13:50
  • + means "one or more". I suggest you write a self-contained failing example and post that, and the errors you're getting, in a new question. – RichieHindle Jun 23 '09 at 14:31
  • `"[^/?*:;{}\\]+"` can be dangerous in some cases, cause it validates filename like `.` or `..` – rap-2-h Jun 19 '12 at 10:21
  • 2
    Why did you not include delimiters? `/^[^\/\?\*:;{}\\\]+\.[^\/\?\*:;{}\\\]+$/` – Gajus Jan 09 '13 at 01:39
  • @GajusKuizinas: Because the delimiters aren't a part of the regular expression itself. – RichieHindle Jan 09 '13 at 09:03
6
$a = preg_match('=^[^/?*;:{}\\\\]+\.[^/?*;:{}\\\\]+$=', 'file.abc');

^ ... $ - begin and end of the string
[^ ... ] - matches NOT the listed chars.
hegemon
  • 6,614
  • 2
  • 32
  • 30
2

The regex would be something like (for a three letter extension):

^[^/?*:;{}\\]+\.[^/?*:;{}\\]{3}$

PHP needs backslashes escaped, and preg_match() needs forward slashes escaped, so:

$pattern = "/^[^\\/?*:;{}\\\\]+\\.[^\\/?*:;{}\\\\]{3}$/";

To match filenames like "hosts" or ".htaccess", use this slightly modified expression:

^[^/?*:;{}\\]*\.?[^/?*:;{}\\]+$
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • You can of course you something other than "/" to delimit the regex in preg_match(), this removes the need to escape forward slashes specifically, but adds the need to escape the new delimiter character (if you want to use it in the regex). – Tomalak Jun 23 '09 at 12:13
  • 2
    Warning ! A filename like `.` or `..` can be dangerous in some case, and is valid with `^[^/?*:;{}\\]*\.?[^/?*:;{}\\]+$` – rap-2-h Jun 19 '12 at 10:17
1

Below the regex using for checking Unix filename in a Golang program :

    reg := regexp.MustCompile("^/[[:print:]]+(/[[:print:]]+)*$")
0

Here is an easy to use solution with specific file extensions:

$file = 'file-name_2020.png';
$extensions = array('png', 'jpg', 'jpeg', 'gif', 'svg');
$pattern = '/^[^`~!@#$%^&*()+=[\];\',.\/?><":}{]+\.(' . implode('|', $extensions). ')$/u';

if(preg_match($pattern, $discount)) {
    // Returns true
}

Keep in mind that special characters allowed in this scenario are only - and _. To allow more, just remove them from $pattern

richardev
  • 976
  • 1
  • 10
  • 33