2013-05-13 51 views
0

我已經搜索了該網站,沒有找到我正在尋找的東西。 密碼標準:用於密碼匹配的正則表達式

  1. 必須是6個字符,最多50
  2. 必須包括1個字母字符
  3. 必須包括1數字或特殊字符

下面是我在Java:

public static Pattern p = Pattern.compile(
"((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])|(?=.*[\\[email protected]#$%^&*\\(\\)_+\\{\\}\\[\\]\\?<>|_]).{6,50})" 
); 

問題是密碼1234567匹配(它是有效的)哪個它不應該。

任何幫助將是偉大的。

+5

我永遠不會使用RegEx來驗證密碼。手動驗證它會更好更快。 – 2013-05-13 17:46:25

+4

爲每個案例創建3個正則表達式,然後通過AND操作一起驗證。 – 2013-05-13 17:47:21

+4

您可能想要分解要求。特別是如果您計劃通知用戶他們的密碼爲什麼不符合要求。如果你把它全部放在一個陳述中,你不能說出哪些需求未得到滿足,也不能告訴他們具體的原因。 – BLuFeNiX 2013-05-13 17:49:30

回答

0

請確保您使用Matcher.matches()方法,它斷言整個字符串相匹配。

您當前的正則表達式:

"((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])|(?=.*[\\[email protected]#$%^&*\\(\\)_+\\{\\}\\[\\]\\?<>|_]).{6,50})" 

表示:

  • 字符串必須至少包含一個數字(?=.*\\d),小寫英文字母(?=.*[a-z]),並以大寫字母(?=.*[A-Z])
  • OR |該字符串必須包含至少一個可能是數字或特殊字符的字符(?=.*[\\[email protected]#$%^&*\\(\\)_+\\{\\}\\[\\]\\?<>|_])
  • 上述任何一個條件都成立,字符串長度必須在6到50個字符之間,並且不包含任何行分隔符。

正確正則表達式是:

"(?=.*[a-zA-Z])(?=.*[\\[email protected]#$%^&*()_+{}\\[\\]?<>|]).{6,50}" 

這將檢查:

  • 字符串必須包含一個英文字母字符(大寫或小寫)(?=.*[a-zA-Z]),和字符,其可以是數字或特殊字符(?=.*[\\[email protected]#$%^&*()_+{}\\[\\]?<>|])
  • 該字符串必須在6到50個字符之間,並且不包含任何行parator。

注意,我刪除轉義字符最多,除了[],因爲{}?()失去字符類中仍然具有特殊意義。

5

我不會嘗試使用單個正則表達式來做到這一點。正則表達式在變長和複雜時往往不會表現良好。

boolean valid(String password){ 
    return password != null && 
    password.length() >= 6 && 
    password.length() <= 50 && 
    password.matches(".*[A-Za-z].*") && 
    password.matches(".*[0-9\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_+\\{\\}\\[\\]\\?<>|_].*"); 
} 
+0

此外,您的代碼將更易於維護。很少有人可以瀏覽一個複雜的正則表達式並理解它正在做什麼。 – 2013-05-13 18:17:00

0

我建議拆分成獨立的正則表達式

$re_numbers = "/[0-9]/"; 
$re_letters = "/[a-zA-Z]/"; 

兩者必須匹配和長度分別測試了。代碼看起來很乾淨,而且更易於理解/更改。

+0

問題是關於Java正則表達式。這個想法很好,但。 – nhahtdh 2013-05-13 18:06:59

0

這樣太複雜,這樣一個簡單的任務:

驗證長度使用字符串#長度()

password.length() >= 6 && password.length() <= 50 

驗證各組使用匹配器#查找()

Pattern alpha = Pattern.compile("[a-zA-Z]"); 
boolean hasAlpha = alpha.matcher(password).find(); 
Pattern digit = Pattern.compile("\d"); 
boolean hasDigit = digit.matcher(password).find(); 
Pattern special = Pattern.compile("[\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_+\\{\\}\\[\\]\\?<>|_]"); 
boolean hasSpecial = special.matcher(password).find(); 
1

甲正則表達式只能匹配可以表示爲確定性有限自動機的語言,即不需要記憶。由於您必須計算特殊字母和字母字符,所以這確實需要記憶,因此您無法在DFA中執行此操作。您的規則很簡單,但您可以掃描密碼,確定其長度並確保所需字符可用。

+0

您在理論正則表達式和編程語言中使用的「正則表達式」之間混淆不清。 Java/.NET/PHP中的「正則表達式」在理論上並不完全是正則表達式,所以它們比理論正則表達式強大得多。 – nhahtdh 2013-05-13 17:55:58

+0

唯一有意義的補充是回溯,它不允許完整的上下文無關語言,我想,並且幾乎肯定不會解決這個問題。 – Joel 2013-05-13 18:04:47

+0

Java正則表達式不允許使用完全上下文無關語言,但.NET正則表達式和PHP正則表達式可以正確進行括號匹配。 – nhahtdh 2013-05-13 18:08:00

1

我建議你分開字符和長度驗證:

boolean checkPassword(String password) { 
    return password.length() >= 6 && password.length() <= 50 && Pattern.compile("\\d|\\w").matcher(password).find(); 
}