Лучший способ сделать это - не использовать регулярные выражения.
Подпрограмма с отдельными условиями гораздо легче читать и поддерживать:
sub is_password_valid {
my ($pw) = @_;
$pw =~ m{[^a-zA-Z0-9!\#+,\-./:=\@_]}
and return 0;
length($pw) >= 10 && length($pw) <= 32
or return 0;
$pw =~ /(.)\1{9}/s
and return 0;
$pw =~ /^[a-zA-Z0-9]/
or return 0;
($pw =~ /[a-zA-Z]/ + $pw =~ /[0-9]/ + $pw =~ /[^a-zA-Z0-9]/) >= 2
or return 0;
return 1;
}
Или альтернативно, поскольку это в основном одно большое условие:
sub is_password_valid {
my ($pw) = @_;
return
$pw !~ m{[^a-zA-Z0-9!\#+,\-./:=\@_]} &&
length($pw) >= 10 &&
length($pw) <= 32 &&
$pw !~ /(.)\1{9}/s &&
$pw =~ /^[a-zA-Z0-9]/ &&
($pw =~ /[a-zA-Z]/ + $pw =~ /[0-9]/ + $pw =~ /[^a-zA-Z0-9]/) >= 2
;
}
Если это не игрушечный валидатор для домашнего задания, вам следует изменить свои требования. Не имеет смысла "проверять" пароли с помощью регулярного выражения.
Вместо этого вам следует указать минимальную длину, намного большую максимальную длину (возможно, 255 символов или около того) и не ограничивать используемый набор символов.
Если вы хотите защитить от слабых паролей, проверьте против haveibeenpwned и дайте взломщику паролей (например, hashcat ) попробовать.