【问题标题】:Regex doesn't recognize underscore as special character正则表达式不将下划线识别为特殊字符
【发布时间】:2015-10-01 17:46:25
【问题描述】:
/(?=^.{8,}$)(?=.*[_!@#$%^&*-])(?=.*\d)(?=.*\W+)(?![.\n])(?=.*[a-z])(?=.*[A-Z]).*$/

我正在尝试为密码验证制作一个正则表达式,这样密码必须至少为 8 个字符,并且包括一个大写字母、一个小写字母、一个数字和一个特殊字符。它工作正常,但它不会将下划线 (_) 识别为特殊字符。即,Pa$$w0rd 匹配,但 Pass_w0rd 不匹配。想法?

【问题讨论】:

  • 答案真的很简单。您没有在特殊字符中包含 _
  • 那是一些看起来很邪恶的正则表达式。你确定要使用正则表达式来做这样的事情吗?随着需求的变化,它可能会变得难以维护。
  • David B,实际上因为这个正则表达式使用了前瞻断言,它可能对可维护性很好。每个部分都是模块化的,不依赖任何其他部分。
  • 我已经想知道正则表达式如何确保字符串包含所有多组字符并具有最小长度。 +1 用于问题和解释,因为这是我还没有想到的非常酷的方法。 :-)

标签: regex


【解决方案1】:

这部分正则表达式似乎在寻找特殊字符:

(?=.*[!@#$%^&*-])

请注意,字符类不包含下划线,请尝试将其更改为以下内容:

(?=.*[_!@#$%^&*-])

您还需要修改或删除这部分正则表达式:

(?=.*\W+)

\W 等同于[^a-zA-Z0-9_],因此如果下划线是您唯一的特殊字符,这部分正则表达式将导致它失败。相反,将其更改为以下内容(或删除它,这是多余的,因为您之前已经检查过特殊字符):

(?=.*[^\w_])

完整的正则表达式:

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

【讨论】:

  • 糟糕,忘记在我的代码 sn-p 中包含该修订。它仍然不接受 Pass_w0rd :(
【解决方案2】:

这里的这个也可以。它通过排除字母数字字符和空格来定义特殊字符,因此它包括下划线:

(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[\d])(?=.*?[^\sa-zA-Z0-9]).{8,}

【讨论】:

  • 这似乎适用于所有角色。但不占空间
【解决方案3】:

问题在于,根据定义,唯一可能满足\W 的东西是[a-zA-Z0-9_] 以外的东西。 \W 明确不匹配下划线,而在Pass_w0rd 中,也没有其他任何内容与之匹配。

我怀疑同时拥有您的特殊字符 的特定列表 \W 是矫枉过正。选择一个,你可能会更快乐。我还建议将整个事情分成几个单独的测试,以获得更好的可维护性。

【讨论】:

  • 谢谢!不过,我真的不擅长正则表达式,你知道我该如何解决吗?
  • 我添加了一个可能的解决方案
【解决方案4】:

适用于您的更简单的正则表达式是:

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

您的原始正则表达式中几乎没有错误,例如:

  • 您无需使用前瞻来确保输入中有 8 个字符
  • 负前瞻[.\n] 丢失.*
  • (?=.*\W+) 是多余的,可能没有任何目的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-17
    • 2019-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多