I'm trying to extend this regex to match 3 of 4 submatches.
First, you have 5 submatches, not 4
Then, let's fix what you already have.
should be/^.*(?=.{10,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$/
/^(?=.{10})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#\$%^&+=])/s
In short, .*.* is (very) slow and useless. Similarly, /.{10,}/ also does needless work compared to /.{10}/. And of course, you didn't mean to use the variable $%.
That whole thing means
so you could do/.{10}/s && /\d/ && /[a-z]/ && /[A-Z]/ && /[@#\$%^&+=]/
orlenght() >= 10 && /\d/&&1 + /[a-z]/&&1 + /[A-Z]/&&1 + /[@#\$%^&+=]/&&1 + == 4 or die;
use List::Util qw( sum ); lenght() >= 10 && sum( /\d/, /[a-z]/, /[A-Z]/, /[@#\$%^&+=]/ ) == 4 or die;
"&& 1" is required in scalar context since m// is not guaranteed to return 1 for successful matches in scalar context.
But you really want that in a match op, don't you?
m{ (?{ 0 }) ^ (?> (?=.{10}) (?=.* \d (?{ $^R+1 }) | ) (?=.* [a-z] (?{ $^R+1 }) | ) (?=.* [A-Z] (?{ $^R+1 }) | ) (?=.* [@#\$%^&+=] (?{ $^R+1 }) | ) ) (?(?{ $^R != 3 })(?!)) }xs or die;
Update: AnomalousMonk pointed to me that $% is a bug. I adjusted the post accordingly.
In reply to Re: Password Regex optimization
by ikegami
in thread Password Regex extended
by 3dbc
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |