preg_match for。 /或\在PHP中

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 = '%(\.|\\\\|/)%'