我想爲密碼字符串,至少包含三個出以下四種類型的字符的正則表達式:什麼是以下約束的正則表達式?
- 英文小寫字符(a到z)。
- 英文大寫字母(通過Z)。
- 基數10位數字(0到9)。
- 非字母數字字符(例如!,$,#,%)。
而且應該至少包含8個字符。
我想爲密碼字符串,至少包含三個出以下四種類型的字符的正則表達式:什麼是以下約束的正則表達式?
而且應該至少包含8個字符。
正確答案:
正則表達式:?。?。
^((= [\ d])(= [ AZ])(= [AZ])|?(= [AZ])(= [AZ])(= [^ \ W \ d \ S])|????(= [\ d ??])(= [AZ])(= [^ \ W \ d \ S])|。???(= [\ d])(= [AZ])(= [^ \瓦特\ d \ s]))。{8,30} $
謝謝。
鑑於怪物一個,這些要求可能會產生,我懷疑你實際上是將是更好做這個作爲多個檢查,像(僞代碼):
def check_password (s):
if len(s) < 8:
return false
rules_followed = 0
if match (s, "[a-z]") rules_followed++;
if match (s, "[A-Z]") rules_followed++;
if match (s, "[0-9]") rules_followed++;
if match (s, "[!$#%]") rules_followed++; # et cetera
if rules_followed < 3:
return false
return true
當其他人必須維護您的代碼時(或者即使必須從現在起六個月後才能維護它),這可能會更具可讀性。
現在我意識到這可能並不總是可能的(例如,你可能會被一個只允許一個正則表達式進行驗證的框架卡住)。
但是,如果它是可能,我強烈建議您考慮它。 第一個你應該總是試圖優化的東西是可讀性。
一個你要麼與那些大規模的前瞻正則表達式的一個或多個包含由|
訂貨分隔十六可能性單一的正則表達式結束。
這些都不會像簡單的代碼段那樣高效或可讀。
+1比編寫正則表達式來測試4種類型的所有可能組合更容易。 – 2011-05-26 06:10:03
組合並沒有那麼糟糕 - 只有四種方法可以從四種可能性中選出三種;你可以在正則表達式的開始測試那些向前看符號,然後檢查八個字與實際不符:
^(?:(?=.*[A-Z])(?=.*[a-z])(?=.*\d)|(?=.*[A-Z])(?=.*[a-z])(?=.*[_\W])|(?=.*[A-Z])(?=.*\d)(?=.*[_\W])|(?=.*[a-z])(?=.*\d)(?=.*[_\W])).{8}
(錨定是效率失敗時,它會工作沒有它)。
對於密碼它可能沒有關係,但上面的版本可能會在相同類型的字符中多次查看整個字符串,尤其是在失敗時。你可能因素出來就是這樣,在可讀性成本:
^(?:(?=.*[A-Z])(?:(?=.*[a-z])(?:(?=.*\d)|(?=.*[_\W]))|(?=.*\d)(?=.*[_\W]))|(?=.*[a-z])(?=.*\d)(?=.*[_\W])).{8}
擴展PCRE版本:
/^(?:
(?=.*[a-z]) # look ahead: at least one from a-z
(?=.*[A-Z]) # look ahead: at least one from A-Z
(?=.*[0-9]) # look ahead: at least one from 0-9
| # or...
(?=.*[a-z]) # look ahead: at least one from a-z
(?=.*[A-Z]) # look ahead: at least one from A-Z
(?=.*[^a-zA-Z0-9]) # look ahead: at least one from special chars
| # or...
(?=.*[a-z]) # look ahead: at least one from a-z
(?=.*[0-9]) # look ahead: at least one from 0-9
(?=.*[^a-zA-Z0-9]) # look ahead: at least one from special chars
| # or...
(?=.*[A-Z]) # look ahead: at least one from A-Z
(?=.*[0-9]) # look ahead: at least one from 0-9
(?=.*[^a-zA-Z0-9]) # look ahead: at least one from special chars
)
\S{8,} # at least 8 non-spaces
$/x
首先,這裏的paxdiablo的代碼C#編譯:
public bool Validate(string input)
{
if (input == null || input.Length < 8)
return false;
int counter = 0;
if (input.Any(Char.IsLower)) counter++;
if (input.Any(Char.IsUpper)) counter++;
if (input.Any(Char.IsDigit)) counter++;
if (input.Any(c => Char.IsPunctuation(c) || Char.IsSymbol(c))) counter++;
return counter >= 3;
}
如果您堅持使用正則表達式,您可以使用類似於Fun With .NET Regex Balancing Groups上的圖案:
^
(?=.*[a-z](?<Counter>))?
(?=.*[A-Z](?<Counter>))?
(?=.*[0-9](?<Counter>))?
(?=.*[^a-zA-Z0-9](?<Counter>))?
(?<-Counter>){3} # check we've had at least 3 groups
.{8}
您還可以讓Unicode classes:
^
(?=.*\p{Ll}(?<Counter>))?
(?=.*\p{Lu}(?<Counter>))?
(?=.*\p{Nd}(?<Counter>))?
(?=.*[\p{S}\p{P}](?<Counter>))?
(?<-Counter>){3}
.{8}
@Chris - 如果我沒有錯,RegularExpressionValidator正在使用客戶端JavaScript正則表達式,它不支持這些功能。另一個選擇是它試圖從頭到尾匹配,所以你需要'。{8,}'而不是'。{8}',但我認爲這不會有幫助。 – Kobi 2012-02-13 19:24:26
這實際上看起來像一個**要求**(對SO思路不太歡迎) – V4Vendetta 2011-05-26 05:47:38
8個字符 - 是最大的,還是長度可以小於8? – VMAtm 2011-05-26 06:01:37
字符串的最小長度爲8個字符。 – 2011-05-26 06:33:15