2016-06-13 111 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 

"""