寻找另一个正则表达式解释



在我的regex表达式中,我试图匹配8到16个字符之间的密码,其中每个至少包含以下两个字符:小写字母,大写字母和数字。

在我的表达式中,我有:

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

但我不明白为什么它不能这样工作:

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

不"。"*"仅仅意味着"零或多个字符"?如果我只是检查特定的条件,为什么我需要这个呢?

为什么我需要花括号前的句号来定义密码的限制?

还有一件事,我不明白引用"?="时"不消耗任何字符串"是什么意思。

你的最后两个问题是相关的。?=(顺便说一下,它被称为前瞻性)不消耗字符串的任何内容,这意味着它测试字符串的条件,但它本身是零字符长。如果前瞻性为真,则继续匹配,但是表达式的下一部分从检查前瞻性之前的位置开始。

因为你所有的东西都是由前看组成的,它们的长度加起来都是0个字符。所以,为了让{8,16}匹配,你需要先供给..{8,16}表示"8到16个字符,我不关心这些字符是什么。"{8,16}之前没有任何内容,它不是一个有效的表达式(或者至少不会表示.{8,16}的意思)。

关于你的第一个问题,你需要.*在你的每个头,因为你的表达式开始于^。这意味着"从字符串的最开头开始",而不是"在字符串的任何地方匹配"。因为您不需要只在字符串的开头匹配,所以.*允许您在字符串的任何地方进行预查找。

最后,恐怕你的regexp不起作用。因为前瞻是零长度的,将相同的前瞻放入两次将匹配相同的内容两次。因此,这个表达式只检查您是否有每个类型的字符的单个实例,您想要强制有两个实例。您想要的表达式更像这样:

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

这个表达式等价于更优雅的:

^((?=(.*d){2})(?=(.*[a-z]){2})(?=(.*[A-Z]){2}).{8,16})$
(而且,在该表扬的地方,丹尼斯在最后一个表达上胜过了我。干得好,先生。

问题是这个字符^意味着"Right on start"之类的东西。这意味着这些特定的字符应该严格地出现在你正在搜索的文本的开头,这不是你想要的。

你的表达式不能按你想的那样工作。

由于预先查找,(?=.*d)的两个实例实际上将匹配相同的数字,因此仅用一个数字验证密码。

这个应该可以工作:

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

(?=.*d)(?=d)之间的区别在于,虽然它们都是零宽度的前看,但前者将匹配如果字符串中任何地方有一个数字(在当前位置之后),但后者将匹配只有当该数字紧接在当前位置之后。因此,第一个正则表达式查找8-16个字符,包括一个数字、小写字母和大写字母。第二个正则表达式要求第一个字符是数字、小写字母和大写字母,这是荒谬的。如果你想计算两位数,那么用(?=.*d.*d)代替(?=.*d)(?=.*d)

最新更新