2013-07-22 52 views
0

我已被授予任务来验证密码时,其即将被更改。 该口令需要:正则表达式的密码政策不起作用

  • 到最小的8个字符长
  • 具有至少一个大写字母
  • 具有至少一个小写字母
  • 具有至少一个数字
  • 具有在至少有一个特殊字符

这是我正在使用的正则表达式:

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

由于我不是正则表达式方面的专家,我一直在关注tutorial on Code Project(我发现它非常有帮助)。虽然我花了超过30分钟阅读教程,但我仍然无法掌握问题所在。

问题:
正则表达式查找一切,但特殊字符。我没有看到问题。

当我在寻找答案时,我碰到了derekslager.com blog,它有一个很好的测试表达式页面。

+0

在工作中的正则表达式尝试此'((?=。* \ d)(?=。* [AZ])(?=。* [AZ])(?=。 * [@#$%])。{8,20})' – Dotnet

+0

你在d'(?=。* \\ d)'之前有一个双反斜杠。尝试删除它,它应该工作。你的方式,你会要求你的密码包含'\ d'(字面意思)至少一次,而不是“至少一个数字” –

+0

....我的意思是删除双反弹,只留下一个,如下所示: '(?=。* \ d)' –

回答

5

你在你的正则表达式一个微妙的缺陷:

[@#$%&+=-_] 
     ^

字符类中的一个破折号指定character range,这意味着如果任一下列字符都在你的人物类将注册一个“积极的”匹配您的密码:

@,#,$,%,&,+,=,>,?A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X ,Y,Z,[,\],^ _

如果调换-_,就可以避免这个问题:

[@#$%&+=_-] 

破折号位于无论是在第一或最后一个位置在字符类中失去其特殊含义并被视为文字破折号。

此外,您不需要.*在模式的开始和结束。你的零宽度断言(aka“lookaheads”)已经包含.*,所以这是多余的,只会导致你的正则表达式在负面匹配上放慢速度。如果您仅使用正则表达式来测试输入,那么你就可以在第一个字符开始,不需要捕获任何:

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

如果你想捕捉的密码,以及,那么你可以使用:

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

只是为了笑声,如果你想绑定在密码最多,你可以从你的第一个前瞻内如此设置:

^(?=.{8,30}$) 

如果你想允许您的用户包括carriag e在密码中返回,请务必使用Singleline flag

参见regexplanet.comregexhero.net

+0

首先感谢您花时间提供详细的答案。我正在使用此http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx网站来测试您提供的soloution(s),但它们都不是给我一场比赛。我的代码中的正则表达式是使用一个stringbuilder构建的,我不得不改变每一个小部分。我不介意这样做,如果我确定它会工作,但它没有通过即时通讯使用的“测试”网站,这让我怀疑它会起作用吗? – ThunD3eR

+0

@ Ra3IDeN - 我显然无法说明你如何构建正则表达式,因为你没有发布该代码,但是这个正则表达式*将根据你所布置的参数进行匹配。我已经用链接更新了我的答案。 (你在使用JavaScript在客户端执行此匹配?如果是这样,那么你的lookahead不被支持,因为它们包含[无限重复](http://www.regular-expressions.info/lookaround.html)。) – JDB

+0

我不知道你的链接是否有问题,但我当我尝试它时出现错误...“编译正则表达式时出错” 我没有共享字符串builde代码,因为我初始认为这将是你/他人通过该代码翻阅的负担,我专注于正则表达式。它没有在JavaScript中完成它在后端代码 – ThunD3eR

0

有人纠正我,如果我错了,但如果密码可以是任何组合的需求,你正在寻找你可能需要一次验证他们一个,但如果模式将永远是相同的,然后一行正则表达式应该做的伎俩,例如,如果它总是会像这样:

Qwe12;,. 
[Capital Letter(s)][lowercase letter(s)][number(s)][special character(s)] 

然后正则表达式的一个行会比较容易拿出来验证,但如果它可以成为你的质量要求如的任意组合

weQ,.12 

12we,.Q 

然后,它可能会更容易验证一次一个如此:

First check for caps [A-Z] 
Then lowercase [a-z] 
Then numbers [0-9] 
Then special characters [[\^$.|?*+()] 

因此,如果任何一个失败的密码是无效的,希望这有助于。

+0

你是不正确的。零宽度断言允许“探测”前方找到特定模式,而不用“移动”该位置。它基本上就像在队列或堆栈中“窥视”前一样,而没有真正的“弹出”。 (这是可能的,因为.NET正则表达式的风格允许无限表达式在前瞻/后面) – JDB

+0

也就是说,每次检查一个条件并不是一个可怕的想法。如果你想让管理员能够启用/禁用特定的密码检查,或者你想允许可扩展性(插入自定义密码验证器)等,这将是非常有用的。有时单线程方法会在系统内产生刚性这可能是不可取的。 – JDB

+0

酷感谢纠正我我不知道你可以探讨前进 – Srb1313711