Regex соответствует сильному паролю с двумя или более специальными символами

Мне нужно регулярное выражение совместить поле пароля с помощью javascript со следующими требованиями:

  • Не менее 15 символов
  • два или более строчных буквы
  • два или более строчных буквы
  • две или более цифры
  • два или более следующих специальных символа:! @# $% ^ & * -

У меня есть регулярное выражение, которое заботится о случаях MOST:

/^.*(?=.{15,})(?=.{2,}\d)(?=.{2,}[a-z])(?=.{2,}[A-Z])(?=.{2,}[\!\@\#\$\%\^\&\*\-]).*$/

Проблема здесь в символах, она работает с:

[email protected]@ssw0rd
[email protected]@
[email protected]@Pssw0rd

Но не:

@@Pssw0rdPssw0rd

У меня есть генератор случайных паролей, чтобы полностью проверить это, поэтому любые идеи очень ценятся. Спасибо!

Ответ 1

/^(?=(?:.*[a-z]){2})(?=(?:.*[A-Z]){2})(?=(?:.*\d){2})(?=(?:.*[[email protected]#$%^&*-]){2}).{15,}$/

Ваши взгляды ошибочны. Образец

(?=.{2,}[class])

означает совпадение 2 или более символов (независимо от того, какие символы), а затем 1 символ желаемого класса. Это полностью отличается от "2 или более символов желаемого класса", которые вы указали.

Чтобы правильно проверить, есть ли символ желаемого класса в тексте, используйте

(?=.*[class])

и поскольку вы хотите проверить его дважды, повторите шаблон

(?=.*[class].*[class])
# equivalent to (?=(?:.*[class]){2})

Ответ 2

Я не уверен, что одно повторное выражение - это способ пройти этот тест.

Лично я бы реализовал его примерно так: (рассматривайте как псевдокод, я его не тестировал)

function testPassword(pw) {
    var len = pw.length;
    if(len < 15) return false;
    if(pw.replace(/[a-z]/,'').length > len - 2) return false;
    if(pw.replace(/[A-Z]/,'').length > len - 2) return false;
    if(pw.replace(/[0-9]/,'').length > len - 2) return false;
    if(pw.replace(/[[email protected]#$%^&*-]/,'').length > len - 2) return false;
    return true;
}

Ответ 3

Уже есть несколько хороших объяснений, поэтому я просто собираюсь...

/^
(?= .{15} )
(?= (?:.*[[:lower:]]){2} )
(?= (?:.*[[:upper:]]){2} )
(?= (?:.*[[:digit:]]){2} )
(?= (?:.*[[email protected]#$%^&*-]){2} )
/x