2016-06-13 112 views
-4

我想確認,如果用戶的密碼是:正則表達式3

  1. 由8個字符
  2. 由數字和字母
  3. 至少有一個大字母和一個數字
  4. 它應該包含$或!要麼 ?
  5. 的順序並不重要

我的代碼是:

r.match(r'([A-Z]+)([a-z])([0-9]+)($|?|!){8}',password) 

它是正確的答案?我不知道如何指定,這個順序在正則表達式中並不重要。

EDITED 使用提出了一些建議我已經編輯我的代碼:

m = re.compile(r'^(?=.*\d)(?=.*[A-Z])(?=.*[\$|\?\!])[A-Za-z\d$!&]{8}$') 
m.match('adwA12f!') 
<_sre.SRE_Match object; span=(0, 8), match='adwA12f!'> 

能否請你,如果能夠澄清一下,究竟是什麼? 「=」。在正則表達手段。

+1

您是否對任何字符串進行過測試?請添加到問題。正則表達式與您所描述的不匹配。 –

+0

一個簡單的方式來說,順序並不重要,是單獨測試模式 –

+0

我不認爲試圖解決它在一個正則表達式是一個好主意。爲了提高可讀性和可測試性,請使用多重檢查來解決問題,例如像完成[這裏](http://stackoverflow.com/a/32542964/771848)。 – alecxe

回答

1

這似乎工作在IDLE 2.7.9測試。 ;

string matched 

?=是在先行斷言:請記住,這僅與8個字符

^(?=.*[!$?])(?=.*[a-z])(?=.*[A-Z]).{8}$

import re 
p = re.compile('^(?=.*[!$?])(?=.*[a-z])(?=.*[A-Z]).{8}$') 
test_str = 'a2Cd$F!8' 
if re.search(p, test_str): 
    print('string matched') 

輸出相匹配建議閱讀本網站:"Lookahead Assertion"

.匹配除換行符外的任何字符;由於您有方括號,因此.僅限於[]中定義的內容;也被稱爲原子分組。

+1

更新爲更嚴格的版本 – Chris

0

我想最明顯的非正則表達式的方法是:

symbols = '$!?' 
if (len(pwd) >= 8 and 
     any(c.isdigit() for c in pwd) and 
     any(c.isupper() for c in pwd) and 
     any(c in symbols for c in pwd) and 
     all(c.isalnum() or c in symbols for c in pwd)): 
    print('good password') 
else: 
    print('bad password') 

你沒有說出來,但我相信你至少需要一個小寫了。如果是的話添加這個條款以及

any(c.islower() for c in pwd) 
0

至少在我的系統上,做檢查,而無需使用re快一點。而且,隨着密碼長度的增加,速度差異似乎變得更加明顯。

import re 
import timeit 

passwords_varied = ("kk", "999999999999999999999999", "kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", "gkrDsh!2", "gjtlssssssssssssssssfsdg43ggw3fa2adada2fagaa2adajjjjjjjjjjjjjjjkhjkhjkhjkd45!", "kit43MM?", "fkthrej!", "483kkED!") 

passwords_8chars = ("hktj33cD", "!?gk329s", "fkrK44?a", "dlekAS2$", "??ffD913") 

def check1(s): 
    return len(s) == 8 and \ 
    any(x.isdigit() for x in s) and \ 
    any(x in ("$","!","?") for x in s) and \ 
    any(x.isupper() for x in s) 

def check2(s): 
    if len(s) == 8 and \ 
    re.search(r"\d", s) and \ 
    re.search(r"[$!?]", s) and \ 
    re.search(r"[A-Z]", s): 
     return True 
    return False 

def run1(passwords): 
    for password in passwords: 
     check1(password) 

def run2(passwords): 
    for password in passwords: 
     check2(password) 


def main(): 
    print ("---- list comprehension approach ----") 
    print ("varying length passwords") 
    print(timeit.timeit("run1(passwords_varied)", setup="from __main__ import run1, passwords_varied", number=100000)) 
    print ("correct length passwords") 
    print(timeit.timeit("run1(passwords_8chars)", setup="from __main__ import run1, passwords_8chars", number=100000)) 
    print "" 
    print "---- 're' approach ----" 
    print ("varying length passwords") 
    print(timeit.timeit("run2(passwords_varied)", setup="from __main__ import run2, passwords_varied", number=100000)) 
    print "correct length passwords" 
    print(timeit.timeit("run2(passwords_8chars)", setup="from __main__ import run2, passwords_8chars", number=100000)) 


if __name__ == '__main__': 
    main() 


""" 
---- list comprehension approach ---- 
varying length passwords 
2.69666814804 
correct length passwords 
3.31486010551 

---- 're' approach ---- 
varying length passwords 
3.27806806564 
correct length passwords 
4.286420106 

"""