NoviceCoding
NoviceCoding

Reputation: 6361

Regex without pattern delimiters doesn't emit Warning with preg_match()

$first = ".";
$last = "a";
$middle= "testing-123.test";

if (preg_match("[a-zA-Z0-9]", $first)){
 echo 'Frist Returned valid.';
}
if (preg_match("[a-zA-Z0-9.-]", $middle)){
 echo 'Middle Returned valid.';
}
if (preg_match("[a-zA-Z0-9]", $last)){
 echo 'Last Returned valid.';
}

I am breaking down a string into 3 parts using substr so in this example the original text was ".testing-123.testa". I didnt include the substr here but just predefined the variables in this case. I want to check so it means the following requirements:

First character: a-z, A-Z, 0-9 NO SYMBOLS

middle character: a-z, A-Z, 0-9, only . and - symbols

Last character: same as first character.

When I ran above code it echo'd nothing. Any ideas?

Upvotes: 0

Views: 81

Answers (3)

mickmackusa
mickmackusa

Reputation: 47903

Despite your coding intention, all of your regex patterns are treating the opening square brace and the closing square brace as pattern delimiters. This is happening because some non-identical characters can be used as pattern delimiters. Because your pattern is technically valid, no Warning is emitted to complain about missing delimiters. As a consequence, your character class is not treated as a characters class and is instead interpreted as a pattern containing mostly literal characters (only the . is treated as a metacharacter). Demo showing that a-zA-Z0-9 and a-zA-Z0-9#- will be deemed valid. A basic solution is to wrap your patterns in forward slashes.

Also, your patterns do not validate the entire string -- they only check if as little as 1 character is matched. To validate the full string, you need to match the start of the string with ^, require one or more characters with +, then match the end of the string with $.

Ultimately, regex should only be used when there isn't a simpler solution. To simply check if a string is completely comprised of alphanumeric characters, the most ideal call is ctype_alnum().

Recommended solution: (Demo)

$first = ".";
$last = "a";
$middle= "testing-123.test";

echo "First segment:\t" . (ctype_alnum($first) ? 'valid' : 'invalid') . "\n";
echo "Second segment:\t" . (preg_match("/^[a-z\d.-]+$/i", $middle) ? 'valid' : 'invalid') . "\n";
echo "Third segment:\t" . (ctype_alnum($last) ? 'valid' : 'invalid');

Output:

First segment:  invalid
Second segment: valid
Third segment:  valid

Upvotes: 0

Tim Pietzcker
Tim Pietzcker

Reputation: 336208

if (preg_match("/^[a-z0-9]+$/i", $first)){
 echo 'First Returned valid.';
}
if (preg_match("/^[a-z0-9.-]+$/i", $middle)){
 echo 'Middle Returned valid.';
}
if (preg_match("/^[a-z0-9]+$/i", $last)){
 echo 'Last Returned valid.';
}

should do what you need.

You need delimiters (/), and you need to make sure that all characters are tested from the beginning to the end of the string (^ and $ anchors).

Upvotes: 0

Sarfraz
Sarfraz

Reputation: 382746

You are missing delimitters, try adding / around your regex:

if (preg_match("/[a-zA-Z0-9]/", $first)){
 echo 'Frist Returned valid.';
}
if (preg_match("/[a-zA-Z0-9.-]/", $middle)){
 echo 'Middle Returned valid.';
}
if (preg_match("/[a-zA-Z0-9]/", $last)){
 echo 'Last Returned valid.';
}

You might also want to use preg_match_all to find more/all instances.

Upvotes: 4

Related Questions