Thought
Thought

Reputation: 5856

Combination of rules with Regex

In an android project, im trying to validate a password that the user inputs, and it must follow some rules

The rules are: it must have 7 characters and 3 of the following conditions

**

-One lowercase character

-One uppercase character

-One number

-One special character

**

for example:

asd123!!!

PPPppp000

TTT999###

i was trying with this regex

^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{7,}+$

but this enforces all rules at same time.

Upvotes: 1

Views: 100

Answers (2)

Aaron
Aaron

Reputation: 24812

Without going into the details of your lookaheads (which seem correct), here's how you would need to implement "three out of four criteria" in pure regex :

(?=.*A)(?=.*B)(?=.*C)|(?=.*A)(?=.*B)(?=.*D)|(?=.*A)(?=.*C)(?=.*D)|(?=.*B)(?=.*C)(?=.*D)

You can test it here.

Factorizing doesn't really make it better :

(?=.*A)(?:(?=.*B)(?=.*(?:C|D))|(?=.*C)(?=.*D))|(?=.*B)(?=.*C)(?=.*D)

I obviously recommend using a higher level language to implement these sorts of constraints.

Upvotes: 2

Asunez
Asunez

Reputation: 2347

The approach is wrong here. The regex you created looks like a monster from under the bed, and is highly illegible even for someone regex-literate.

Why not split it into 4 (or as much as there are rules) regexes and check against whether 3 of them return a match? Not only will you make your regexes cleaner, but you will be able to add more rules if need be without changing whole regex.

You can also use inbuilt methods for checking (if applicable under Android development kit).

Some pseudocode would look like this:

result1 = Regex.IsMatch(password, rule1regex)
result2 = Regex.IsMatch(password, rule2regex)
...
resultN = Regex.IsMatch(password, rule3regex)

if(three_out_of_four_rules_apply)
    password_valid = true

You can also apply method suggested in comments by @pskink and iterate over each character of a password and set the output accordingly.

Upvotes: 3

Related Questions