Home » Php » php – My regex correctly doesn't accept a string online, but preg_match() returns true

php – My regex correctly doesn't accept a string online, but preg_match() returns true

Posted by: admin February 25, 2020 Leave a comment

Questions:

I have this regular expression /^([email protected])([^#\s\\\\]|(\\\d{3}))*$/.

It’s supposed to accept strings that start with [email protected], then all characters but #, \, or any whitespace characters can follow. \ can only appear when it’s followed by 3 digits.

When I test this regex with the string [email protected]\07test on regex101.com and phpliveregex.com, no matches are found (correctly), but preg_match() returns true for the same string.

What am I doing wrong?

Thank you

UPDATE:

$regex = "/^([email protected])([^#\s\\]|(\\d{3}))*$/";

preg_match($regex, '[email protected]'); # this returns false, as it should

preg_match($regex, "[email protected]"); # this returns true

The test string is taken from a file using fgets() and stored in a variable, though, so I can’t pass it to preg_match() and put apostrophes around it, I need to pass the variable ($string, for example), and preg_match($regex, $string) incorrectly returns true again.

How to&Answers:

First things first:

'\07' is a string of length 3 beginning with a backslash character.

"\07" is a string of length 1 consisting of ASCII x’07’

Interactive shell

php > echo strlen('');
3
php > echo strlen("");
1
php >

See PHP Strings

Regex:

/^[email protected](?:[^#\s\]|\(?=\d{3}))*$/

See Regex Demo

  1. ^ Matches start of string.
  2. [email protected] Matches [email protected]
  3. [^#\s\\] Matches any character other than #, white space or \.
  4. | or
  5. \\(?=\d{3}) Matches \ if followed by 3 digits.
  6. (?: expression 3 through 5)* matched 0 or more times.
  7. $ Matches the end of string.

Code:

<?php
$tests = [
    'abcd',
    '[email protected] test',
    '[email protected]#test',
    '[email protected]',
    '[email protected]',
    '[email protected]'
];

$regex = '/^[email protected](?:[^#\s\\]|\\(?=\d{3}))*$/';
foreach ($tests as $test) {
    if (preg_match($regex, $test)) {
        echo "$test\n";
    }
}

Prints:

[email protected]
[email protected]