2010-09-27 65 views
73

我正在創建一個用於密碼驗證的正則表達式,以便在Java應用程序中用作配置參數。Regexp用於密碼驗證的Java

的正則表達式是:

^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$ 

的密碼策略是:

  • 至少8個字符

  • 至少包含一個數字

  • 至少包含一個較低的阿爾法炭和一個較高的阿爾法焦炭

  • 包含一套特殊字符的(@#%$^等)

  • 不包含空格,標籤內的至少一個char等

我只是缺少點5。我無法對空格,製表符,回車等進行正則表達式檢查。

任何人都可以幫助我嗎?

+0

密碼規則是壞的。請參閱[參考 - 密碼驗證](https://stackoverflow.com/questions/48345922/reference-password-validation)以獲取更多信息。 – ctwheels

回答

201

試試這個:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$ 

說明:

^     # start-of-string 
(?=.*[0-9])  # a digit must occur at least once 
(?=.*[a-z])  # a lower case letter must occur at least once 
(?=.*[A-Z])  # an upper case letter must occur at least once 
(?=.*[@#$%^&+=]) # a special character must occur at least once 
(?=\S+$)   # no whitespace allowed in the entire string 
.{8,}    # anything, at least eight places though 
$     # end-of-string 

這很容易添加,修改或刪除個別規則,因爲每個規則是一個獨立的 「模塊」。

(?=.*[xyz])構造吃完整個字符串(.*)並回溯到[xyz]可匹配的第一個匹配項。如果找到[xyz],則成功,否則失敗。

另一種方法是使用一個不情願的限定詞:(?=.*?[xyz])。對於密碼檢查,這幾乎沒有任何區別,對於更長的字符串,它可能是更有效的變體。

當然,最有效的變體(但最難讀取和維護,因此最容易出錯)應該是(?=[^xyz]*[xyz])。對於這個長度的正則表達式,爲了這個目的,我會不推薦這樣做,因爲它沒有真正的好處。

+11

@ Kerby82:在Java字符串中,反斜槓必須被轉義。嘗試使用'\\ s'。這是Java的要求,而不是正則表達式的要求。 – Tomalak

+0

yes \ t是無意義的,因爲\ s包含一個空格字符:[\ t \ n \ x0B \ f \ r]。但是現在在java中反斜槓的工作完美。非常感謝! – Kerby82

+0

如果您需要在其他所有環境中使用(?-m:...),則可以顯式關閉多行模式作爲正則表達式的一部分 –

33

簡單的例子使用正則表達式

public class passwordvalidation { 
    public static void main(String[] args) { 
     String passwd = "[email protected]"; 
     String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}"; 
     System.out.println(passwd.matches(pattern)); 
    } 
} 

說明:

  • (?=.*[0-9])一個數字必須出現至少一次
  • (?=.*[a-z])小寫字母必須出現至少一次
  • (?=.*[A-Z])上部病例信件必須至少發生一次
  • (?=.*[@#$%^&+=])必須出現特殊字符至少一次
  • (?=\\S+$)沒有空格允許的整個字符串中
  • .{8,}至少8個字符
+3

。{5,10}代表最少5個字符,最多10個字符。以防萬一有人在尋找具體的解釋。 – iabhi

+0

@iabhi,我一直在尋找這個。謝謝。 –

1

密碼要求:

  • 密碼應至少八個(8)個字符,系統可以支持它。
  • 密碼必須包含至少兩個這樣的分組中的字符:字母,數字和特殊字符。

    ^.*(?=.{8,})(?=.*\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\d)(?=.*[[email protected]#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[[email protected]#$%^&]).*$ 
    

我測試了它和它的作品

0

我認爲這是可以做到這一點也(爲簡單模式):

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])[^\s]{8,}$ 

[Regex Demo]

9

所有先前給出的答案使用相同的(正確的)技術爲每個需求使用單獨的前瞻。但是它們包含了一些效率低下和潛在的巨大bug,具體取決於實際使用密碼的後端。

我會從接受的答案正則表達式開始:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$ 

首先,因爲Java支持\A\z我更喜歡使用那些以確保整個字符串被驗證,獨立的Pattern.MULTILINE 。這不會影響性能,但可避免正則表達式回收時的錯誤。

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}\z 

檢查該密碼不包含空格和檢查它的最小長度可以在單次通過使用一次全部通過將可變量詞{8,}上限制允許的字符的速記\S來完成:

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])\S{8,}\z 

如果提供的密碼確實包含空格,則所有檢查都將完成,只是爲了讓最終檢查在空間上失敗。這可以通過\S更換所有的點來避免:如果你真的想允許任何字符

\A(?=\S*[0-9])(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[@#$%^&+=])\S{8,}\z 

的點,才應使用。否則,使用(否定)字符類將您的正則表達式限制爲僅允許那些真正允許的字符。雖然在這種情況下沒有什麼區別,但not using the dot when something else is more appropriate是一個很好的習慣。我看到太多的例子catastrophic backtracking,因爲開發者懶得使用比點更合適的東西。

因爲有一個很好的機會,在最初的測試將在密碼上半年找到一個合適的角色,一個懶惰的量詞可以更快捷:

\A(?=\S*?[0-9])(?=\S*?[a-z])(?=\S*?[A-Z])(?=\S*?[@#$%^&+=])\S{8,}\z 

但現在真正重要的問題:沒有的答案中提到了一個事實,即原來的問題似乎是由某人以ASCII形式進行思考的。但在Java中,字符串是Unicode。密碼中是否允許使用非ASCII字符?如果是,則只允許ASCII空格,或者應排除所有Unicode空格。

默認情況下,\s僅匹配ASCII空格,因此它的逆\S匹配所有Unicode字符(不包括空格)和所有非空白ASCII字符。如果允許Unicode字符但Unicode空格不允許,則可以指定UNICODE_CHARACTER_CLASS標誌使\S排除Unicode空格。如果不允許Unicode字符,則可以使用[\x21-\x7E]而不是\S來匹配不是空格或控制字符的所有ASCII字符。

這給我們帶來了下一個潛在問題:我們想要允許控制字符嗎?編寫正確的正則表達式的第一步是準確地指定要匹配的內容以及不匹配的內容。唯一100%技術上正確的答案是,問題中的密碼規範是不明確的,因爲它沒有說明是否允許某些範圍的字符,如控制字符或非ASCII字符。

3

你不應該使用過於複雜的正則表達式(如果你能避免他們),因爲他們是

  • 難以閱讀(至少對於每個人,但你自己)
  • 很難擴展
  • 難以調試

儘管在使用很多小規則表達式時可能會有小的性能開銷,但上面的點很容易就能輕鬆實現。

我想實現這樣的:

bool matchesPolicy(pwd) { 
    if (pwd.length < 8) return false; 
    if (not pwd =~ /[0-9]/) return false; 
    if (not pwd =~ /[a-z]/) return false; 
    if (not pwd =~ /[A-Z]/) return false; 
    if (not pwd =~ /[%@$^]/) return false; 
    if (pwd =~ /\s/) return false; 
    return true; 
} 
+0

從安全角度來看,強制更長的密碼,防止衆所周知的密碼(如12345和pass = user)要好得多,而不是使密碼變得非常複雜和難以記住。 –

0

任何有興趣在每類角色的最低要求,我建議做以下擴展了託默勒格的接受的答案:

^(?=(.*[0-9]){%d,})(?=(.*[a-z]){%d,})(?=(.*[A-Z]){%d,})(?=(.*[^0-9a-zA-Z]){%d,})(?=\S+$).{%d,}$ 

注意這是一個格式化字符串,而不是最終的正則表達式模式。只需將%d替換爲數字,小寫字母,大寫字母,非數字/字符以及整個密碼(分別)的最小必需出現次數即可。最大出現次數是不太可能的(除非你想最大值爲0,有效地拒絕任何這樣的字符),但也可以很容易地添加。注意每種類型的額外分組,以便最小/最大限制允許非連續匹配。這對於我們可以集中配置我們需要的每種字符類型的系統的奇蹟,然後讓網站以及兩個不同的移動平臺獲取該信息以基於上述格式字符串來構建正則表達式模式。

0

容易一個

(「^(?=。* [0-9])(?=。* [AZ])(?=。* [AZ])(?=。* [\\ W _])\\ S] {8,10} $「)

  1. (=什麼)? - >表示正期待着在所有輸入的字符串,並確保這個條件被寫入。樣品(=? 。* [0-9]) - >表示確保在所有字符串中寫入一位數字。如果不寫入返回錯誤
  2. (?!anything) - >(反之亦然)表示否定期待條件爲寫入返回false

    接近意義^(條件)(條件)(條件)(條件)[\ S] {8,10} $

+0

雖然代碼只回答可能會提供解決方案,但一些解釋會大大提高答案的質量。 –