2011-11-26 70 views
0

在我的正则表达式中,我试图匹配8到16个字符之间的密码,每个字母至少有2个:小写字母,大写字母和数字。寻找另一个正则表达式的解释

在我的表情,我有:

^((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,16})$ 

但我不明白为什么它不会像这样工作的:“*”

^((?=\d)(?=[a-z])(?=[A-Z])(?=\d)(?=[a-z])(?=[A-Z]){8,16})$ 

犯规只是意味着“零个或多个任何字符“?那么,如果我只是在检查特定条件,为什么还需要这些?

为什么我需要花括号定义密码限制之前的时间段?

还有一件事,我不明白“参考”?=“时不要使用任何字符串”是什么意思。

+3

这个正则表达式实际上并没有做你说的那样。它匹配只有一个大写字母和一个数字的字符串“A1aaaaaa”。 – Godwin

回答

2

你最后两个问题是相关的。 ?=(顺便提一句,它叫做lookahead)不会消耗任何字符串,这意味着它测试字符串的一个条件,但它本身是零字符长。如果前瞻是真的,那么匹配将继续,但表达式的下一部分从检查前瞻之前的位置开始。

因为你所有的东西都是由lookaheads组成的,所以它们全部加起来长度为零。因此,为了匹配{8,16},您需要首先提供..{8,16}的意思是“8到16个字符,我不在乎这些字符是什么。” {8,16}没有任何东西之前,它不是一个有效的表达式(或至少不会意味着什么.{8,16}意味着什么)。

关于您的第一个问题,您需要在每个lookahead中使用.*,因为您的表达式以^开头。这意味着“从字符串的一开始就开始”而不是“匹配字符串中的任何位置”。由于您不是只在字符串的开始处尝试匹配,因此.*允许您在字符串中的任何位置具有预览。

最后,我怕你的正则表达式不起作用。因为前视图是零长度的,所以将两个视图放在同一个视图中,两次匹配相同的视图。所以这个表达式只会检查你是否有一个你想强制执行的每个类型的字符的实例,这里有两个实例。你想表达的是更多这样的:

^((?=.*\d.*\d)(?=.*[a-z].*[a-z])(?=.*[A-Z].*[A-Z]).{8,16})$ 

那表情就相当于更优雅:

^((?=(.*\d){2})(?=(.*[a-z]){2})(?=(.*[A-Z]){2}).{8,16})$ 

(而且,给予信贷,这是由于,丹尼斯击败了我,去年的表达。干得好,先生。)

1

问题是,这个字符^意味着像'开始正确'。这意味着这些特定的字符应该严格限定在你搜索的文本的开头,这不是你想要的。

1

你的表情不会按你所希望的那样工作。

由于前瞻性,(?=.*\d)的两个实例实际上都会匹配相同的数字,因此只验证一个数字的密码。

这应该工作:

^(?=(.*\d){2})(?=(.*[a-z]){2})(?=(.*[A-Z]){2}).{8,16}$

1

(?=.*\d)(?=\d)之间的不同之处在于,虽然它们都是零宽度向前看符号,是,如果有一个数字的字符串中的任何前者将匹配(在当前位置之后),但后者只有在该位数紧跟当前位置之后才匹配。所以,第一个正则表达式会查找8-16个字符,每个字符包括一个数字,一个小写字母和一个大写字母。第二个正则表达式要求第一个字符是一个数字,一个小写字母和一个大写字母,这是荒谬的。如果你想数学两位数,那么代替(?=.*\d)(?=.*\d),做(?=.*\d.*\d)