0

i have this function:

public static function encPasswordCheckFailed($password)
    {
        if (!preg_match('/[A-Z]+/', $password)){
            return true;
        }
        if (!preg_match('/[a-z]+/', $password)){
            return true;
        }
        if (!preg_match('/[0-9]+/', $password)){
            return true;
        }
        if (!preg_match('/[!@#$%^&*()-+<>]+/', $password)) {
            return true;
        }

        return false;
    }

and now i want to force the user to have at least 1 Uppercased Letter, 1 Lowercased Letter, 1 Number and 1 Specialcharacter.

I'm having the problem with this:

if (!preg_match('/[!@#$%^&*()-+<>]+/', $password)) {
    return true;
}

All other requirements work. I have only a problem with the specialcharacters.
Can someone tell me the correct pattern for these specialcharacters: !@#$%^&*()-+<>

i've read some of the answers from here, here and here but they didn't help me further...

Community
  • 1
  • 1
Blueblazer172
  • 588
  • 2
  • 15
  • 44
  • 1
    From first sight.. escape the `-`, though it's not that harmful in this case. What exactly is not working? – Sebastian Proske Nov 16 '16 at 10:10
  • Tried this http://stackoverflow.com/questions/22544250/php-password-validation? – Abhishek Nov 16 '16 at 10:10
  • 1
    look at Doruk Ayar answer. You have to escape (\) special characters for regex to "see" them as characters. – boroboris Nov 16 '16 at 10:13
  • Just escape the dash `-` or move it at the begining or at the end of the character class. – Toto Nov 16 '16 at 10:16
  • still not woking... – Blueblazer172 Nov 16 '16 at 10:23
  • What is not working? What do you get? What are you expecting? Could you show us your test cases? – Toto Nov 16 '16 at 10:24
  • `if (!preg_match('/[!@#$%^&*()+<>-]/', $password))` should trigger if a string has no special chars defined in the char class. See [this demo](https://regex101.com/r/23teqX/2). Since `wxN5n>N1gdtsJyOEGak46hHkNgd4-^` contains some of the special chars, the `!preg_match` will not get triggered. – Wiktor Stribiżew Nov 16 '16 at 10:27
  • the pattern from the answer from below `'/\[!@#$%^&*\(\)-+<>\]+/'` is not working. in my input field i tried to enter a password like: `wxN5n>N1gdtsJyOEGak46hHkNgd4-^` but the functions still returns true. im my case all my errors are handled with true and if it passes the match then it returns false – Blueblazer172 Nov 16 '16 at 10:27
  • Of course, it is wrong! Did you try to escape the dash only? – Toto Nov 16 '16 at 10:30
  • @WiktorStribiżew and what is then the correct way to handle it ? – Blueblazer172 Nov 16 '16 at 10:33
  • @Toto i don't understand your question... – Blueblazer172 Nov 16 '16 at 10:34
  • @Blueblazer172: I do not understand *your* question. `if (!preg_match('/[!@#$%^&*()+<>-]/', $password))` should be the right approach. With this, the result for `encPasswordCheckFailed("wxN5n>N1gdtsJyOEGak46hHkNgd4-^")` is *False*, I guess it is expected. – Wiktor Stribiżew Nov 16 '16 at 10:35
  • @WiktorStribiżew yeah thats right – Blueblazer172 Nov 16 '16 at 10:37
  • 1
    Escape the dash (ie. `[!@#$%^&*()\-+<>]`) or move it at the begining `[-!@#$%^&*()+<>*]` or at the end `[!@#$%^&*()+<>*-]` – Toto Nov 16 '16 at 10:38
  • @WiktorStribiżew why did you close the question.. the pattern from the anser you linked it is not working. look [here](http://www.rubular.com/r/W73yV7AgDL) for me only [this](http://www.rubular.com/r/25dd349idb) worked – Blueblazer172 Nov 16 '16 at 10:54
  • 1
    The answer is: put the `-` to the end/start of the character class as in case it is inside between separate chars it creates a range. Or escape the hyphen. – Wiktor Stribiżew Nov 16 '16 at 10:55
  • @WiktorStribiżew ah ok now i understand :P – Blueblazer172 Nov 16 '16 at 10:57

3 Answers3

2

You may need to escape some special characters used by the Regex Engine. And by the way, you could as well do that in one Go as shown below. Quick-Test Here.

<?php


    /*public static*/ function encPasswordCheckFailed($password) {
        // THIS READS:
        // IF THE PASSWORD DOES CONTAIN AN UPPER-CASE CHARACTER
        // AND ALSO DOES CONTAIN A LOWER-CASE CHARACTER
        // AND STILL DOES CONTAIN A NUMERIC CHARACTER
        // AND EVEN MORE, DOES CONTAIN ANY  OF THE SPECIFIED SPECIAL CHARACTERS 
        // RETURN FALSE OTHERWISE RETURN TRUE
        if (preg_match('/[A-Z]+/', $password) &&                    // CHECK FOR UPPERCASE CHARACTER
            preg_match('/[a-z]+/', $password) &&                    // AND CHECK FOR LOWERCASE CHARACTER
            preg_match('/[0-9]+/', $password)&&                     // AND CHECK FOR NUMERIC CHARACTER
            preg_match('/[\!@#$%\^&\*\(\)\-\+<>]+/', $password)     // AND CHECK FOR SPECIAL CHARACTER
        ) {
            return false;
        }

        return true;
    }

    var_dump( encPasswordCheckFailed("abcd123") );    //<== boolean true
    var_dump( encPasswordCheckFailed("abcD123") );    //<== boolean true
    var_dump( encPasswordCheckFailed("abcD1@23-") );  //<== boolean false
Poiz
  • 7,611
  • 2
  • 15
  • 17
1

The dash/minus character is your issue, as when inside a character group, it denotes a character range.

You need to either:

  • Escape it with a backslash, so that it isn't treated as a special character:
    /[!@#$%^&*()\-+<>]+/
  • Or put it at the end of the pattern, so the PCRE engine knows it can't possibly denote a range:
    /[!@#$%^&*()+<>-]+/

Similarly, the caret (^) is also a special character, denoting negation when inside a character group, but because you didn't put it at the very first position inside the character group, the PCRE engine knows it has no special meaning in your case.

Narf
  • 14,600
  • 3
  • 37
  • 66
0

This will gonna work for special characters:

preg_match('/\[!@#$%^&*\(\)\-+<>\]+/', $password);

If it's not working, look down:

OTHER ANSWERS:

  1. preg_match php special characters (pmm's answer)
Community
  • 1
  • 1
Doruk Ayar
  • 334
  • 1
  • 4
  • 17