2016-05-04 82 views
-1

我需要檢查一個密碼字符串本規則:有沒有合併這兩個正則表達式的方法?

  • 只有小寫字母,大寫字母,數字和一些特殊字符(見下文),是允許的。
  • 的8個字符和最大16
  • 密碼必須的Minimun包含從三個四個下列基團中的至少一個字符:

    • 小寫字母
    • 大寫字母
    • 數字字符
    • 特殊字符(@#$%&/= _,!?;-)

爲了完成這個目標,我做了兩個驗證。最簡單的一個是第一步,請允許的字符和長度:

^[[email protected]\#$%&/=?_.,:;\-]{8,16}$ 

第二個是更復雜一點,但由於我能解決這個問題這個Stackoverflow answer

^((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*[[email protected]\#$%&/=?_.,:;\-])|(?=.*[a-z])(?=.*[0-9])(?=.*[[email protected]\#$%&/=?_.,:;\-])|(?=.*[A-Z])(?=.*[0-9])(?=.*[[email protected]\#$%&/=?_.,:;\-])).{8,16}$ 

我認爲這可能是一個2步驟的解決方案清晰簡單..但是... 有沒有辦法將兩個正則表達式合併?

我想在Java,JavaScript和Lua上應用該解決方案。

回答

1

讓我強調,我不喜歡你的密碼策略開始了。爲什麼你禁止使用其他符號或超過16個字符的密碼?如果可能,請不要包含這些規則。

我寫這個表達式的擴展形式(即忽略空格),爲了清楚:

/\A 
    (?=.{8,16}\z)      # Must contain 8-16 characters 
    (?!.*[^a-zA-Z\[email protected]#$%&\/=?_.,:;-]) # Must not contain other characters 
    (?=.*\d)       # Must contain a digit 
    (?=.*[a-z])      # Must contain a lower case character 
    (?=.*[A-Z])      # Must contain an upper case character 
    (?=.*[[email protected]#$%&\/=?_.,:;-])   # Must contain a symbol from this list 
/x 

上面的圖案解決了執行你的規則全部四個問題。理論上,您可以將最後4個條件包含到四個「或」組中 - 就像您的原始示例所做的那樣。

但是,我不會再推薦它。如果你在一個函數內部做了一系列單獨的檢查,你的代碼將更加清晰,有用並且可維護。 (例如,這意味着您可以顯示更多有用的錯誤消息,而不僅僅是「正則表達式失敗!」。

但是既然您問了....下面是正則表達式怪獸:

/\A 
    (?=.{8,16}\z) 
    (?!.*[^a-zA-Z\[email protected]#$%&\/=?_.,:;-]) 
    (
    (?=.*\d) 
    (?=.*[a-z]) 
    (?=.*[A-Z]) 
    | 
    (?=.*\d) 
    (?=.*[a-z]) 
    (?=.*[[email protected]#$%&\/=?_.,:;-]) 
    | 
    (?=.*\d) 
    (?=.*[A-Z]) 
    (?=.*[[email protected]#$%&\/=?_.,:;-]) 
    | 
    (?=.*[a-z]) 
    (?=.*[A-Z]) 
    (?=.*[[email protected]#$%&\/=?_.,:;-]) 
) 
/x 

移除所有的空格,如果你不想/可以訪問/x修改做。

+0

密碼策略是我的沉默的一個要求,他已經在其他系統中實施了此策略,因此目前很難對其進行更改。感謝@TomLord爲您提供解決方案和建議! –

0

整個驗證的單個正則表達式的缺點是,正則表達式很難讀取和維護。將正則表達式條件分解爲對每個條件的單個檢查以及對String長度的簡單檢查將是一種更合適且更易讀的解決方案。在我看來,以下代碼對密碼的驗證與單個正則表達式一樣好,但維護和讀取更好。

public static void main(String[] args) { 
    System.out.println(isPasswordValid("Ab$123456")); 
    System.out.println(isPasswordValid("b$11234566")); 
    System.out.println(isPasswordValid("Ab$1234634634534252")); 
    System.out.println(isPasswordValid("$112512312512")); 
    System.out.println(isPasswordValid("A$115 223")); 
} 

private static boolean isPasswordValid(String password) { 
    // The password is to short or to long 
    if(password.length() < 8 || password.length() > 16) { 
     return false; 
    } 
    int matchedConditions = 0; 
    // Check for invalid characters 
    if(password.matches(".*[^[email protected]#$%&/=?_.,:;-].*")) { 
     return false; 
    } 
    // is an uppercase letter present, increase matched condition 
    if(password.matches(".*[A-Z].*")){ 
     ++matchedConditions; 
    } 
    // is a lowercase letter present, increase matched condition 
    if(password.matches(".*[a-z].*")){ 
     ++matchedConditions; 
    } 
    // is a numeric value present, increase matched condition 
    if(password.matches(".*[0-9].*")){ 
     ++matchedConditions; 
    } 
    // is a special character present, increase matched condition 
    if(password.matches(".*[[email protected]#$%&/=?_.,:;-].*")){ 
     ++matchedConditions; 
    } 
    // Return if at least 3 conditions were met 
    return matchedConditions >= 3; 
} 

輸出:

true 
true 
false 
false 
false 
+0

謝謝,但您的解決方案將返回此密碼'Ab $ 12 34'的真實性,並且不允許空格,不是嗎? –

+0

@DavidIsla檢查我的編輯,如果你包含一個無效字符的列表,那麼你可以包括你認爲沒有的所有東西。 – SomeJavaGuy

+0

當然,你的解決方案是有效的,這是對的,但我想知道是否有合併的方法。非常感謝! –

相關問題