I am trying to match . \ or / using preg_match in PHP.
I thought this would do it but it's matching all strings.
$string = '';
$chars = '/(\.|\\|\/)/';
if (preg_match($chars, $string) != 0) {
echo 'Chars found.';
}
Argument given to preg_match()
is string. Strings are automatically escaped by PHP. For example, if you have {\\\\}
(backslash) given to the regexp engine, PHP will first parse it creating {\\}
(\\
is replaced by \
).
Next, regexp engine parses the regexp. It sees {\\}
which PHP gave to regexp engine. It sees \
as escape character, so it actually matches \
character which was escaped by \
.
In your case, it looks like /(\.|\\|\/)/
. PHP gives to regexp engine /(\.|\|\/)/
which is actually either .
or |/
(notice that |
character was escaped).
Personally, I try to avoid escaping meta-characters, especially with how regexp engine works. I usually use [.]
instead, it's more readable. Your regexp written with this would look like /([.]|\\\\|[/])/
.
It's possible to do few optimizations. While it's my personal thing, I prefer to use {}
as delimiters (yes, you can use pairs of characters). Also, your regexp matches single characters, so you could easily write it as {[.\\\\/]}
, which is very readable in my opinion (notice four slashes, it's needed because both PHP and regexp engine parse backslashes).
Also, preg_match()
returns number of matches. It will be always bigger than 0
, so you can easily consider it to be boolean and avoid writting == 0
. Instead, you can insert !
before string to make it negative. But I think you accidentally reversed condition (it matches if it doesn't match). Valid code below:
$string = '';
$chars = '{[.\\\\/]}';
if (preg_match($chars, $string)) {
echo 'Chars found.';
}
The issue is probably with PHP. When escaping something in a regex string, you also need to escape the backslashes you use to escape, or PHP will attempt to interpret it as a special character.
As that probably didn't make sense, have an example.
$string = "\."
will make PHP attempt to escape the ., and fail. You instead need to change this to $string = "\\\."
.
Your if
logic is flawed. preg_match
will return the number of matches. Therefore, == 0
means "no matches".
That said, single quoted strings don't expand escape sequences except \'
and \\
. You need to double your backslash escape for it to appear in the regex as expected. Change your code to:
$string = '';
$chars = '/(\.|\\\\|\/)/';
if (preg_match($chars, $string) != 0) {
echo 'Chars found.';
}
Here's a test case:
$strings = array('', '.', '/', '\\', 'abc');
$pattern= '/(\.|\\\\|\/)/'
foreach($strings as $string) {
if (preg_match($pattern, $string) > 0) {
printf('String "%s" matched!', $string);
}
}
When trying to REGEX match slashes, I would strongly suggest using a different separator character than '/'. It reduces the amount of escaping you need to do and makes it much more readable:
$chars = '%(\.|\\|/)%';
Try this:
$chars = '%(\.|\\\\|/)%'