【问题标题】:REGEX to validate password that can't contain some caracters正则表达式验证不能包含某些字符的密码
【发布时间】:2022-01-17 12:55:53
【问题描述】:

我需要检查密码是否符合以下规则:

  • 至少 8 个字符(长度)
  • 一个大写字母
  • 一个小写字母
  • 一个号码
  • 一个特殊字符
  • 不能包含“.”或“_”(棘手的部分)

例如:

  • Bft$ns2E => 应该匹配
  • H2od%^.,3 => 不应该匹配(注意“.”)

我试过了:

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

满足所有规则,除了最后一条(不能包含“.”或“_”)。正则表达式对我来说总是很痛苦,无法弄清楚如何做到这一点。

谢谢大家!

【问题讨论】:

  • 如果您在正则表达式中苦苦挣扎 - 为什么要继续使用它。并不是说它的代码会运行很多次,所以即使拆分它的速度较慢,它也可能更易于维护。
  • 我使用 api 和后端,我想在两个站点中验证密码,我不想在每个 lenguajes 中重复验证功能,我认为使用 ragex 更好。

标签: php regex passwords


【解决方案1】:

您的正则表达式在正确的轨道上。我会使用:

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

这个模式说:

^
    (?=.*?[A-Z])  assert capital letter
    (?=.*[a-z])   assert lowercase letter
    (?=.*\d)      assert digit
    (?=.*\W)      assert non word/special character
    (?!.*[._])    assert NO dot or underscore
    .{8,}         match a password of length 8 or greater
$

【讨论】:

    【解决方案2】:

    使用像 (?=(.*[a-z]){1,}) 这样的前瞻,您可以省略带有量词 {1,} 的组,因为在字符串中断言一次就足够了。

    如果您不想匹配空格 ._,您可以使用 negated character class 匹配 8 次或更多次(不包括这些字符)。

    在前瞻断言中使用否定字符类可以防止不必要的回溯。

    ^(?=[^A-Z\r\n]*[A-Z])(?=[^a-z\r\n]*[a-z])(?=[^\d\r\n]*\d)(?=\w*\W)[^\s._]{8,}$
    

    模式匹配:

    • ^ 字符串开始
    • (?=[^A-Z\r\n]*[A-Z]) 断言一个字符 A-Z
    • (?=[^a-z\r\n]*[a-z]) 断言一个字符 a-z
    • (?=[^\d\r\n]*\d) 断言一个数字
    • (?=\w*\W) 断言一个非单词字符
    • [^\s._]{8,} 匹配除空格字符之外的任何字符 8 次以上 .-
    • $字符串结束

    Regex demo

    【讨论】:

      猜你喜欢
      • 2011-05-05
      • 1970-01-01
      • 2016-12-12
      • 2013-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多