2011-05-26 17 views
1

我想爲密碼字符串,至少包含三個出以下四種類型的字符的正則表達式:什麼是以下約束的正則表達式?

  • 英文小寫字符(a到z)。
  • 英文大寫字母(通過Z)。
  • 基數10位數字(0到9)。
  • 非字母數字字符(例如!,$,#,%)。

而且應該至少包含8個字符。

+0

這實際上看起來像一個**要求**(對SO思路不太歡迎) – V4Vendetta 2011-05-26 05:47:38

+0

8個字符 - 是最大的,還是長度可以小於8? – VMAtm 2011-05-26 06:01:37

+0

字符串的最小長度爲8個字符。 – 2011-05-26 06:33:15

回答

0
我的問題的

正確答案:

正則表達式:?。?。

^((= [\ d])(= [ AZ])(= [AZ])|?(= [AZ])(= [AZ])(= [^ \ W \ d \ S])|????(= [\ d ??])(= [AZ])(= [^ \ W \ d \ S])|。???(= [\ d])(= [AZ])(= [^ \瓦特\ d \ s]))。{8,30} $

謝謝。

10

鑑於怪物一個,這些要求可能會產生,我懷疑你實際上是將是更好做這個作爲多個檢查,像(僞代碼):

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 

當其他人必須維護您的代碼時(或者即使必須從現在起六個月後才能維護它),這可能會更具可讀性。

現在我意識到這可能並不總是可能的(例如,你可能會被一個只允許一個正則表達式進行驗證的框架卡住)。

但是,如果它可能,我強烈建議您考慮它。 第一個你應該總是試圖優化的東西是可讀性。


一個你要麼與那些大規模的前瞻正則表達式的一個或多個包含由|訂貨分隔十六可能性單一的正則表達式結束。

這些都不會像簡單的代碼段那樣高效或可讀。

+5

+1比編寫正則表達式來測試4種類型的所有可能組合更容易。 – 2011-05-26 06:10:03

1

組合並沒有那麼糟糕 - 只有四種方法可以從四種可能性中選出三種;你可以在正則表達式的開始測試那些向前看符號,然後檢查八個字與實際不符:

^(?:(?=.*[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} 
2
正則表達式的

擴展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 
3

首先,這裏的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} 
+1

@Chris - 如果我沒有錯,RegularExpressionValidator正在使用客戶端JavaScript正則表達式,它不支持這些功能。另一個選擇是它試圖從頭到尾匹配,所以你需要'。{8,}'而不是'。{8}',但我認爲這不會有幫助。 – Kobi 2012-02-13 19:24:26