2016-06-01 5 views
3

Я работаю над регулярным выражением, оценивающим качество используемого пароля. Идея состоит в том, что пароль считается посредственным, если он содержит ТОЛЬКО 1 символ верхнего регистра ИЛИ по меньшей мере 6 символов верхнего регистра. Сам пароль должен быть не длиннее 8 символов.Regex для оценки паролей

Желаемая поведение:

AAAAAAAA -> матч

AAAAAAAA -> матч

AAAAAAAA -> не ровня

Я пытался что-то вроде этого:

(?=.*[A-Z]{1,1}|(?=.*[A-Z]{6,})).{8,}

Который doesn ' t сделать трюк, потому что он также соответствует AAaaaaaa. Проблема заключается в первом положительном взгляде, который позволяет использовать 2-5 символов верхнего регистра, но я не мог понять, как этого избежать.

+1

Почему бы 'матч AAaaaaaa'? Он имеет как минимум 1 прописную букву. –

+0

'{1,1}' бесполезно ... –

+0

Если есть одна заглавная буква как условие, она всегда будет успешной, даже если есть две или три или четыре заглавные буквы – rock321987

ответ

2

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

Если вы собираетесь требовать 6 прописных букв в строке, используйте

/^(?=[^A-Z]*[A-Z][^A-Z]*$|.*[A-Z]{6,}).{8,}$/ 
    ^^^^^^^^^^^^^^^^^^^^ 

См this regex demo

Если эти 6 прописных буквы могут быть разбросаны по строке, используйте

/^(?=[^A-Z]*[A-Z][^A-Z]*$|(?:[^A-Z]*[A-Z]){6,}).{8,}$/ 
          ^^^^^^^^^^^^^^^^^^^^ 

Где (?:[^A-Z]*[A-Z]){6,} выполняет поиск по меньшей мере 6 вхождений букв с буквой 0+, а не заглавной буквой. См. this regex demo.

Если вам нужна поддержка Unicode, добавить /u модификатор в конце регулярного выражения, и замените [A-Z] с \p{Lu}, [^A-Z] с \P{Lu}.

Кроме того, рекомендуется использовать \A вместо ^ и \z вместо $, так как это проверка пароля.

Другой регулярное выражение, которое основывается на логике, предложенной bobble bubble:

^       # String start 
(?=.{8,}$)     # 8 or more characters other than a newline 
(?: 
    [^A-Z]*[A-Z][^A-Z]* # a string with 1 uppercase letter only 
    |      # or... 
    (?:[^A-Z]*[A-Z]){6}  # 6 occ. of 0+ chars other than uppercase letters followed with 1 uppercase letter 
    .*      # 0+ chars other than a newline 
) 
$       # string end 

См regex demo и как 1 строка:

/^(?=.{8,}$)(?:[^A-Z\n]*[A-Z][^A-Z\n]*|(?:[^A-Z\n]*[A-Z]){6}.*)$/ 

См this demo.

+0

'^ (? = [^ AZ] * [AZ] [^ AZ] * $ | ([^ AZ] * [AZ]) {6} [^ AZ] * $). {8,} $' – splash58

+0

https : //regex101.com/r/tF1wZ7/4 – splash58

+0

отлично, работает :) – HansGruber

0

Ok. Я думаю, что это не подходящий критерий для надежных паролей, но давайте раскроем вопрос: посчитайте прописные буквы в строке.

Я думаю, что это действительно нелегко сделать, используя regexp. Нужно ли быть одним? Затем вы должны удалить тег php с вопроса ...

PHP-решение: я бы просто отфильтровал заглавные буквы и посчитал их позже.

$caps = strlen(preg_replace('/[^A-Z]+/', '', $pass)); // number of uppercase chars in `$pass` 

$mediocre = strlen($pass) != 8 || $caps > 5 || $caps < 2; 
// mediocre if $pass is not exactly 8 chars long and does not contain between 2 and 5 uppercase characters 
1

Ваш .*[A-Z] также будет использовать верх. Используйте верхние буквы exclusion.

^(?=.{8})(?:([^A-Z]*[A-Z]){6}.*|(?1)[^A-Z]*$) 

Он проверяет, есть ли по крайней мере 6 или ровно 1 верхний, окруженный не верхним.

  • (?=.{8}) опережения при старте проверки по крайней мере 8 символов
  • (?1) является ссылкой на ([^A-Z]*[A-Z])

Больше объяснения и demo at regex101

Смежные вопросы