【问题标题】:Regex to validate password which accept only between fixed length正则表达式验证仅在固定长度之间接受的密码
【发布时间】:2018-02-07 17:39:47
【问题描述】:

我有正则表达式来验证密码,它只接受 10 到 16 之间的密码。

但是,即使我输入超过 16 个字符,它也会返回 true

我的正则表达式是:

^(?=.{10,16})(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=]).*$

【问题讨论】:

  • 为什么选择does not work的解决方案?
  • @Wiktor 我不知道在哪种情况下它不起作用
  • regex101.com/r/sNmqYk/1。嗯,这个答案已经在 3 分钟前更改了,没有锚,它不适用于 matches()
  • @Wiktor 无论如何我正在使用您的正则表达式及其工作

标签: java regex passwords


【解决方案1】:

使用(?=.{10,16}) 前瞻,您设置了最小长度10,16 并不重要,因为您没有在末尾添加$ 告诉在匹配 16 个字符后停止匹配。

您可以在{10,16} 之后添加$,或者删除前瞻并在最后的$ 之前添加{10,16}

我建议遵循规则:前瞻的数量必须是条件数减1(参见rexegg.com for reference):

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=]).{10,16}$
^^^^                                                ^^^^^^^^

See the regex demo.

详情

  • ^ - 字符串开头
  • (?=.*[0-9]) - 至少一位数
  • (?=.*[a-z]) - 至少一个小写 ASCII 字母
  • (?=.*[A-Z]) - 至少一个大写的 ASCII 字母
  • (?=.*[!@#$%^&+=]) - 集合中定义的至少一个特殊字符
  • .{10,16} - 任何 10 到 16 个字符
  • $ - 字符串结束。

在 Java 中,如果在 .matches() 方法中使用模式,则不需要前导 ^ 和尾随 $,因为它需要完整的字符串匹配。

Java:

if (s.matches("(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=]).{10,16}")) {
    return true;
}

【讨论】:

  • 您的解释非常清楚,可以通过有效的解决方案来理解。
【解决方案2】:

你可以简单地使用正则表达式

^[!@#$%^&+=0-9a-zA-Z]{10,16}$

请参阅regex 101 demo

如果您希望密码至少包含 [0-9]、[a-z]、[A-Z]、[!@#$%^&+=] 中的 1 个,那么您可以将您的正则表达式更改为

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=]).{10,16}$

【讨论】:

  • 是的,它会匹配任何给定字符 10 到 16 次
  • @Narendra 不,此正则表达式不符合原始要求。您只需将*$ 替换为{10,16}$。并删除(?=.{10,16})。否则,在(?=.{10,16}) 中添加$ => (?=.{10,16}$)
  • 这是一个错误的答案。如果您提供属于该集合的任何一个字符 [!@#$%^&+=0-9a-zA-Z],您的密码仍然有效。您的期望是密码应至少包含一个A-Z、一个a-z、一个0-9 和一个属于该集合的特殊字符[!@#$%^&+=]
  • @Srichandradeep 和 Wiktor 让我试试你们俩的建议。
  • @Narendra 我发布了一个答案。
【解决方案3】:
(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=])(?=.{10,16})

您的正则表达式的问题是.*$。您正在匹配 0 到无限次之间的字符。 除此之外,一切看起来都很完美。我修改了 Positive lookaheads 的顺序,因为如果你把长度限制放在最后,这个顺序看起来不错。

【讨论】:

  • Why is this answer accepted? It does not work at all. ^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=])(?=.{10,16})$ 模式是另一个从不匹配任何字符串的正则表达式示例。
  • 对不起。我需要删除 ^$ 字符。复制粘贴错误。顺便说一句,我不知道这在 Java 中是否完美运行。这是基于脚本语言语法的。
  • 让我解释一下:^(?=a)$(这基本上是您以前的正则表达式版本简化为)模式与任何字符串都不匹配,因为(?=a) 在字符串开头触发一次(如它在^) 之后,并且需要a 作为字符串中的第一个字符。由于$ 要求在字符串开始后立即结束字符串,因此正则表达式将失败,因为它无法读取字符串中的第一个字符。
猜你喜欢
  • 2016-12-17
  • 2013-03-18
  • 2021-10-02
  • 2020-06-19
  • 2011-05-06
  • 2016-10-19
  • 2011-03-24
相关资源
最近更新 更多