Use regex with lookaheads / lookbehinds for each condition. Something like below:
^(?=(.*[az]){4})(?=.*[AZ])(?=(.*\d){2}).{7,10}$
I think the regex is self-evident, tell me if you want me to explain each part.
Ok, explanation on OP request:
(?=ABC) , (?!ABC) and (?<=ABC) , (?<!ABC) are lookaheads and lookbehinds that correspond to groups before / after your expression and do not include them in the results. The one with = is positive, and the unit is with ! negative.
Here, for example, (?=(.*[az]){4}) ensures that the main expression ( .{7,10} ) has at least 4 lowercase characters. Similarly, we have one for each condition. .{7,10} ensure maximum 10 (minimum 7 - 4 lower + 1 upper + 2 digits)
The presence of such severely limited passwords (for example, usernames like this is even worse) is not recommended, as @SLaks mentions, but makes a good study of regular expressions possible :) In addition, regular expressions are not known for performance, especially gyneor.
source share