Регулярное выражение для применения сложных паролей, соответствующее 3 из 4 правил - PullRequest
43 голосов
/ 12 августа 2010

У меня есть следующие критерии для создания регулярного выражения для пароля, соответствующего следующим правилам:

  1. Пароль должен быть длиной 8 символов (это я могу сделать: -)).

Пароль должен содержать символы как минимум из 3 из следующих 4 правил:

  1. Верхний регистр
  2. Нижний регистр
  3. Номера
  4. Не буквенно-цифровой

Я могу сделать выражение совпадающим со ВСЕМИ этими правилами со следующим выражением:

/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.[\W]).{8,}$/

Но я борюсь ссделать это таким образом, чтобы решить только 3 из 4 правил.

Кто-нибудь может мне помочь с этим?

Ответы [ 4 ]

102 голосов
/ 12 августа 2010

Не используйте одно регулярное выражение, чтобы проверить его.

if (password.length < 8)
  alert("bad password");
var hasUpperCase = /[A-Z]/.test(password);
var hasLowerCase = /[a-z]/.test(password);
var hasNumbers = /\d/.test(password);
var hasNonalphas = /\W/.test(password);
if (hasUpperCase + hasLowerCase + hasNumbers + hasNonalphas < 3)
  alert("bad password");

Если необходимо использовать одно регулярное выражение:

^(?:(?=.*[a-z])(?:(?=.*[A-Z])(?=.*[\d\W])|(?=.*\W)(?=.*\d))|(?=.*\W)(?=.*[A-Z])(?=.*\d)).{8,}$

Это регулярное выражение не оптимизировано для эффективности.Он построен по A·B·C + A·B·D + A·C·D + B·C·D с некоторой факторизацией.Разбивка:

^
(?:
    (?=.*[a-z])       # 1. there is a lower-case letter ahead,
    (?:               #    and
        (?=.*[A-Z])   #     1.a.i) there is also an upper-case letter, and
        (?=.*[\d\W])  #     1.a.ii) a number (\d) or symbol (\W),
    |                 #    or
        (?=.*\W)      #     1.b.i) there is a symbol, and
        (?=.*\d)      #     1.b.ii) a number ahead
    )
|                     # OR
    (?=.*\W)          # 2.a) there is a symbol, and
    (?=.*[A-Z])       # 2.b) an upper-case letter, and
    (?=.*\d)          # 2.c) a number ahead.
)
.{8,}                 # the password must be at least 8 characters long.
$
6 голосов
/ 19 октября 2012

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

(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[@#$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[@#$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$)?

При минимальной длине пароля 8 и максимальной длине 32 вы можете использовать следующее регулярное выражение:

(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,32}$)?(^(?=.*\d)(?=.*[a-z])(?=.*[@#$%^&+=]).{8,32}$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[@#$%^&+=]).{8,32}$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).{8,32}$)?
6 голосов
/ 12 августа 2010

Вы могли бы написать действительно сложное регулярное выражение, чтобы сделать это. Вместо этого я бы предложил написать четыре разных регулярных выражения, по одному для каждого правила, и протестировать их один за другим, посчитав, сколько из них соответствует Если трое из четырех ответили, примите пароль.

1 голос
/ 12 августа 2010

Я бы предложил сделать проверки отдельно, а затем просто подсчитать, сколько совпадений.

(Я бы также не использовал регулярное выражение ни в одном из них, но это только мой личный POV, а именно: они мешаютудобочитаемость и, как правило, код однократной записи)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...