#regex #vbscript #asp-classic
#регулярное выражение #vbscript #asp-классический
Вопрос:
Может кто-нибудь предложить регулярное выражение для проверки пароля со следующими условиями.
- Длина пароля должна быть не менее 12 символов
- Пароль не должен начинаться с цифры
- Пароль должен иметь 3 из следующих 4 характеристик:
- Хотя бы одна заглавная буква (A-Z)
- Хотя бы одна строчная буква (a-z)
- Хотя бы одно число (0-9)
- По крайней мере, один из следующих символов: дефис ( — ), подчеркивание ( _ ), доллар ( $ ), фунт / хэш ( # )
Я использую vbscript и классический ASP.
Заранее спасибо, m0dest0
Комментарии:
1. Для учета характеристик 3/4 вам нужно смехотворно длинное регулярное выражение для проверки всех возможных комбинаций..
2. Почему оно не может начинаться с числа?
3. Я бы не сказал «нелепый», но ненужный, чтобы быть уверенным — это самая сложная часть в этом, и та часть, в которой регулярные выражения плохо выражаются, но процедурное программирование великолепно — вы бы не поручили человеку, который всю жизнь только подметал полы, преподавать ядерную физику,верно? Это все без упоминания о том, что что-то подобное скажет вам только «ДА» или «НЕТ», а не О том, КАКОЕ правило не было выполнено — для чего-то еще отлично подходит процедурное программирование…
Ответ №1:
Хотя это немного громоздко, это может быть выполнено в одном регулярном выражении следующим образом:
Dim myRegExp
Set myRegExp = New RegExp
myRegExp.Pattern = "^(?=.{12})(?![0-9])(?:(?=[^a-z]*[a-z])(?=[^0-9]*[0-9])(?=[^-_$#]*[-_$#])|(?=[^A-Z]*[A-Z])(?=[^0-9]*[0-9])(?=[^-_$#]*[-_$#])|(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])(?=[^-_$#]*[-_$#])|(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])(?=[^0-9]*[0-9]))[A-Za-z0-9-_$#] $"
If myRegExp.Test(SubjectString) Then
' Successful match
Else
' Match attempt failed
End If
Вот прокомментированная версия регулярного выражения: (в синтаксисе PHP в режиме свободного пробела — который может быть прочитан простыми смертными):
$re_password = '/
# Match password having multiple, specific requirements.
^ # Anchor to start of string.
(?=.{12}) # Password must be at least 12 characters long.
(?![0-9]) # Password must not begin with a number.
(?: # Password must have 3 out of 4 characteristics:
# Either... Case 1: (All but R1).
(?=[^a-z]*[a-z]) # R2: At least one lower case letter (a-z).
(?=[^0-9]*[0-9]) # R3: At least one number (0-9).
(?=[^-_$#]*[-_$#]) # R4: At least one of: [-_$#].
| # Or... Case 2: (All but R2).
(?=[^A-Z]*[A-Z]) # R1: At least one upper case letter (A-Z).
(?=[^0-9]*[0-9]) # R3: At least one number (0-9).
(?=[^-_$#]*[-_$#]) # R4: At least one of: [-_$#].
| # Or... Case 3: (All but R3).
(?=[^A-Z]*[A-Z]) # R1: At least one upper case letter (A-Z).
(?=[^a-z]*[a-z]) # R2: At least one lower case letter (a-z).
(?=[^-_$#]*[-_$#]) # R4: At least one of: [-_$#].
| # Or... Case 4: (All but R4).
(?=[^A-Z]*[A-Z]) # R1: At least one upper case letter (A-Z).
(?=[^a-z]*[a-z]) # R2: At least one lower case letter (a-z).
(?=[^0-9]*[0-9]) # R3: At least one number (0-9).
) # End group of 3-out-of-4 alternatives.
[A-Za-z0-9-_$#] # Match the password string.
$ # Anchor to end of string.
/x';
Предполагается, что пароль не может содержать символы, отличные от: [A-Z]
, [a-z]
, [0-9]
и [-_$#]
. Также предполагается, что пароль может содержать символы всех 4 типов.
: «3 из 4 требований» решается здесь методом перебора (путем явного указания всех возможных комбинаций вариантов в виде группы альтернатив — и повторения общих выражений для каждого случая). Это работает здесь, потому что есть только 4 возможных случая для тестирования, но этот метод становится очень громоздким, если есть больше требований (например, «должен соответствовать 5 из 20 требований …»). Как указывали другие, есть определенные преимущества в том, чтобы разбить это на несколько частей, например, у вас может быть собственное сообщение об ошибке для каждого режима сбоя.
Но это может быть достигнуто с помощью одного регулярного выражения!
Редактировать 2011-10-20: повышена эффективность 4-х предварительных выражений требований путем замены звездочек с ленивыми точками на более точные жадные выражения.
Комментарии:
1. Да, смехотворно длинным 🙂 Спасибо, что записали это. У меня не хватило терпения : D. Черт, я даже 1 тебе за усилия 🙂
Ответ №2:
На самом деле не имеет особого смысла пытаться сделать это с помощью одного выражения, как бы потрясающе это ни звучало…
Я бы сделал это с несколькими выражениями, потому что они будут работать быстрее, выглядеть чище, быть более удобными в обслуживании, а результаты можно использовать для получения обратной связи о ТОМ, ПОЧЕМУ пароль не совпадает (если вы хотите быть таким приятным)
Эти выражения будут проверены, как указано:
.{12,} # Password must be at least 12 characters long
^(?!d) # Password must not begin with a number
(.*[A-Z].*) # At least one upper case letter (A-Z)
(.*[a-z].*) # At least one lower case letter (a-z)
(.*[0-9].*) # At least one number (0-9)
(.*[-_$#].*) # At least one of the following symbols: hyphen ( - ), underscore ( _ ), dollar ( $ ), pound/hash ( # )
Оцените каждое логическое значение, затем предоставьте обратную связь, если достаточное их количество не удовлетворено
При этом это очень строгая политика паролей — просто то, что не начинается с числа, значительно облегчает угадывание.
Я думаю, что это МОЖНО было бы поместить в одно регулярное выражение, но idunno — я мог бы обойти это
Комментарии:
1. Просто констатируя очевидное, но вам не нужно регулярное выражение для проверки длины строки,
Len
все должно быть в порядке.2. Отлично, я дам им попробовать. Спасибо
3. @JBert действительно нет — одна из причин, по которой регулярное выражение настолько невероятно простое. Если бы все условия были равны (т.Е. он должен был удовлетворять 5 из 6 условий, я утверждаю, что было бы разумнее использовать регулярное выражение для проверки длины (поместить все регулярные выражения в массив строк и выполнить цикл тестирования), но поскольку вам нужно будет сделать особый случай,это не имеет гораздо большего смысла
Len
, чем делает — и было бы немного чище / понятнее для тех, кто просматривает код4. Ваше выражение:
(.*[A-Z].*)
это путь к катастрофе (см.: Катастрофическое отслеживание . Чтобы гарантировать одно или несколько значений, выражение должно найти только одно , т.е.(?=.*[A-Z])
Ответ №3:
Когда все, что у вас есть, это молоток, а?
Если серьезно, использование регулярного выражения здесь не совсем правильный ответ. Если вы решительно настроены на использование регулярных выражений, то, по крайней мере, разбейте его на несколько случаев и оцените каждый по отдельности.
На моем месте я бы просто написал набор простых функций, которые проверяют каждый случай. Например: один для верхнего / нижнего регистра, один для числа, один для специальных символов, затем основная процедура, которая проверяет, выполнены ли все ваши требования. Как упоминалось выше, одно регулярное выражение для обработки всех этих случаев было бы затруднительным как для записи, так и для обслуживания..
Комментарии:
1. Спасибо за комментарий, поскольку у меня нет опыта работы с регулярными выражениями, я не мог понять, может ли это быть нелепым или даже выполнимым.