问题
Can someone suggest a regular expression for validating a password with the following conditions.
- Password must be at least 12 characters long
- Password must not begin with a number
- Password must have 3 out of the following 4 characteristics:
- At least one upper case letter (A-Z)
- At least one lower case letter (a-z)
- At least one number (0-9)
- At least one of the following symbols: hyphen ( - ), underscore ( _ ), dollar ( $ ), pound/hash ( # )
I'm using vbscript and classic ASP.
Thanks in advance, m0dest0
回答1:
When all you have is a hammer eh?
Seriously though, using a regex is not really the correct answer here. If you're dead set on using regexes, then at least break it up into multiple cases and evaluate each individually.
If it were me, I'd just write a set of simple functions that check each case. Eg: one for upper/lower case, one for number, one for special symbols, then a main routine that checks that all your requirements are met. As FailedDev mentioned above, a single regex to handle all these cases would be a pain to both write AND maintain..
回答2:
Although a bit unwieldy, this can be accomplished in a single regex like so:
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
Here is a commented version of the regex: (in PHP free-spacing mode syntax - which can be read by mere mortals):
$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';
This assumes that a password may not contain characters other than: [A-Z]
, [a-z]
, [0-9]
and [-_$#]
. It is also assumed that a password may contain characters from all 4 types.
The: "3 out of 4 requirements" is solved here by brute force (by explicitly specifying all possible case combinations as a group of alternatives - and repeating the common expressions for each case). This works here because there are only 4 possible cases to be tested, but this method grows very unwieldy if there are more requirements (e.g. "must meet 5 out of 20 requirements..."). As others have stated, there are definite advantages to breaking this up into multiple parts, e.g. you can have a custom error message with each failure mode.
But this can be accomplished with a single regex!
Edit 2011-10-20: Improved efficiency of the 4 requirements lookahead expressions by replacing the lazy-dot-stars with more precise greedy expressions.
回答3:
It really doesn't make much sense to try and do this with a single expression, as awesome as that sounds...
I would do it with multiple expressions, because they will run faster, look cleaner, be more maintainable, and the results can be used to provide feedback as to WHY the password doesn't match (should you want to be that nice)
These expressions will validate as indicated:
.{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 ( # )
Evaluate each one to a boolean, then provide feedback if enough of them are not satisfied
That being said, this is a very restrictive password policy - just the not starting with a number makes it considerably easier to guess.
I think it COULD be put into one regex, but idunno - I might get around to it
来源:https://stackoverflow.com/questions/7827484/regex-for-password-validation-asp