简体   繁体   中英

preg_match for . / or \ in 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.';
}

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);
    }
}

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 = "\\\\\\." .

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

尝试这个:

$chars = '%(\.|\\\\|/)%'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM