Richard Paulicelli
Richard Paulicelli

Reputation: 119

PHP How do I get this preg_match Regex to work?

I have to have a regular expression that contains at least one lowercase letter, uppercase letter, number, and symbol (non letter or number). I must also contain no spaces and must be between 8 and 16 characters long. I must use the 0-9a-zA-z Expression. I cannot use any other to represent the letters and numbers.

I have run into a few problems which I hope you guys can help me with. I will seperate the issues with line.



1) Quantifier not working

    <?php

        $Password = "Fondulious16";

        echo preg_match("/[0-9a-zA-Z]{8,16}[^\s]/", $Password);


    ?>

Now, It does return 0 if i change the password to go below 8 chacters. But it still returns a 1 if I go above 16 characters.



2) Requirements not working

If I change the brackets to parenthesis it always returns 0 and I can remove the capital letter. So i need to make it to where It will require a capital, lower case, and number. I've tried adding in the + symbol but to no avail:

    <?php

        $Password = "Fondulious16";

        echo preg_match("/[0-9+a-z+A-Z+]{8,16}[^\s]/", $Password);      

    ?>

This did nothing, and nothing changed when I changed the password to something like "fondulious".

    <?php

        $Password = "Fondulious16";

        echo preg_match("/(0-9a-zA-Z){8,16}[^\s]/", $Password);     

    ?>

This always returns 0.



Thanks in advance for any help.

Upvotes: 0

Views: 898

Answers (2)

raheem.unr
raheem.unr

Reputation: 877

Please look at the below example

    if (!preg_match('/([a-z]{1,})/', $value)) {
    // atleast one lowercase letter
}

        if (!preg_match('/([A-Z]{1,})/', $value)) {
    // atleast one uppercase letter
}

if (!preg_match('/([\d]{1,})/', $value)) {
    // altelast one digit
}

if (strlen($value) < 8) {
             // atleast 8 characters length

}

Upvotes: 0

Mario
Mario

Reputation: 36487

Your problem in both cases is the fact that [^\s] is essentially the same as \S; in short: Anything but a space character.

So this last part of the expression will match anything as long as there is indeed at least some character (i.e. not the end of the string).

Also you can't use the + quantifier within one selection/range ([...]). It's just a normal character in there and by default the quantifier following will be able to pick any valid character as often as necessary (there's no easy way to force the elements to be unique anyway).

So, to fix your problem, you should use the following regular expression:

<?php
    $password = "Fondulious16";
    echo preg_match('/^\w{8,16}$/', $password);
?>

Here's a short explanation of the elements:

  • ^ will match the beginning of the string.
  • \w will match any alphanumerical character plus underscores (essentially [a-z0-9_], but case-insensitive).
  • {8,16} is a quantifier "8 to 16 times" as you used it.
  • $ will match the end of the string.

If you don't want underscores to be valid, you can use the following variant.

<?php
    $password = "Fondulious16";
    echo preg_match('/^[0-9a-z]{8,16}$/i', $password);
?>

You might have noticed that I didn't list uppercase characters. Instead, I've used the modifier i after the trailing delimiter (/i) which will tell the algorithm to ignore the case of all characters when trying to match them.


Although it's important to note that this check will not force the user to use lowercase and uppercase characters as well as numbers. It will only check whether the user used any other characters (like punctuation or spaces) as well as the length!

To force the user to use all those things in addition, you can use the following check:

<?php
    $password = "Fondulious16";
    echo preg_match('/[A-Z]/', $password)   // at least one uppercase character
        && preg_match('/[a-z]/', $password) // at least one lowercase character
        && preg_match('/\d/', $password);   // at least one number
?>

If you'd like to do these checks and you want to verify the length as well, then you can use the following expression to look for illegal characters (and a simple string length check to ensure the length is fine):

<?php
    $password = "Fondulious16";
    echo ($pwlen = strlen($password)) >= 8 && $pwlen <= 16 // has the proper length
        && preg_match('/[A-Z]/', $password)         // at least one uppercase character
        && preg_match('/[a-z]/', $password)         // at least one lowercase character
        && preg_match('/\d/', $password)            // at least one number
        && !preg_match('/[^a-z\d]/i', $password); // no forbidden character
?>

Upvotes: 3

Related Questions