正则表达式不将下划线识别为特殊字符。

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

我正在尝试创建一个用于密码验证的正则表达式,以便密码至少为8个字符,并包含一个大写字母、一个小写字母、一个数字和一个特殊字符。它可以很好地工作,但它无法将下划线(_)识别为特殊字符。也就是说,Pa$$w0rd匹配,但Pass_w0rd不匹配。你有什么想法吗?


3
答案非常简单。你没有在特殊字符中包括“_”。 - OmnipotentEntity
这是一些非常复杂的正则表达式。你确定要在这种情况下使用正则表达式吗?随着需求的变化,它可能会变得难以维护。 - David B
1
David B,实际上,由于这个正则表达式使用了前瞻断言,因此它在可维护性方面可能是很好的。每个部分都是模块化的,不依赖于任何其他部分。 - OmnipotentEntity
我曾经想过正则表达式如何确保一个字符串包含多个字符集并且具有最小长度。对于这个问题和解释点赞,因为这是一种非常酷的方法,我之前没有想到过。 :-) - Wormbo
4个回答

3
这部分正则表达式似乎是在寻找特殊字符:
(?=.*[!@#$%^&*-])

请注意,字符类中不包括下划线,请尝试将其更改为以下内容:
(?=.*[_!@#$%^&*-])

你还需要修改或删除该正则表达式的一部分:
(?=.*\W+)

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

(?=.*[^\w_])

完整的正则表达式:

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

1
哎呀,我忘记在我的代码片段中包含那个修订版了。它仍然不接受Pass_w0rd :( - user1436111

2
这个也可以。它将一个特殊字符定义为不包括字母数字字符和空格,因此它包括下划线:
(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[\d])(?=.*?[^\sa-zA-Z0-9]).{8,}

1
这似乎对所有字符都有效。但是不包括空格。 - Jay Star

1
问题在于,根据定义,唯一可能满足\W的是除了[a-zA-Z0-9_]之外的其他内容。下划线明确不与\W匹配,在Pass_w0rd中,它也没有匹配到其他任何内容。
我怀疑同时使用您特定的特殊字符列表和\W有些过头了。选择一个并且你可能会更加满意。我还建议将整个测试拆分成几个单独的测试,以便更好地维护。

谢谢!我真的很不擅长正则表达式,你知道我该怎么解决吗? - user1436111
我已经添加了一个可能的解决方案。 - Jan Krüger

1
一个更简单的适合你的正则表达式是这个:
/(?=.*[_!@#$%^&*-])(?=.*\d)(?!.*[.\n])(?=.*[a-z])(?=.*[A-Z])^.{8,}$/

你原始的正则表达式中有一些错误,例如:

  • 您不需要使用 lookahead 来确保输入中有 8 个字符
  • 负向 lookahead [.\n] 缺少 .*
  • (?=.*\W+) 是多余的,可能没有任何作用

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接