首页 > 解决方案 > 在正则表达式中搜索字母数字密码

问题描述

我一直在尝试创建一个可以检测长度在 5-20 个字符之间的字母数字密码的正则表达式。这些密码可以包含特殊字符 ( @$!%*#?&£)。我的尝试要么没有检测到我的所有测试用例,要么会产生大量误报。

正则表达式目前看起来像这样:

\b(?=.*[a-zA-Z])(?=.*\d*)(?=.*[@$!%*#?&£]*)[a-zA-Z\d@$!%*#?&£]{5,20}(?<![a-zA-Z ])\b

这是我在 Regexr 上运行的正则表达式和我的测试用例

正则表达式的标准如下:

在编写原始正则表达式时,我在应用字符边界时遇到了很多问题,比如说如果一个单词是 21 个字符,我根本不希望它被检测到。我基本上只想扫描这个长度之间的项目,但是这个边界已经阻止了许多匹配被检测到。

取字符串“Rese7”和“Rese7A”。第一个字符串匹配 && 第二个不匹配,我怀疑这是因为我如何实现字符检查。我基本上希望正则表达式做以下事情:

我不确定我是否考虑到这一点,我查看了其他字母数字密码问题,但答案看起来并不能满足我的测试用例:

谢谢你的帮助!

标签: regexregex-lookarounds

解决方案


在您的模式中,您使用这些积极的前瞻(?=.*\d*)(?=.*[@$!%*#?&£]*) ,您想要断言的内容应该匹配 0+ 次数字或使用 asterix 的特殊字符*

因此,如果它存在或不存在,断言将是正确的,这将永远是正确的,给你比你预期的更多的匹配。

您可以使用锚来断言字符串的开头^和结尾$,并省略*以匹配它至少 1 次以确保它在那里。

最后的否定后视(?<![a-zA-Z ])确保左边的不是 char a-zA-Z 或空格。您可以通过不允许空格匹配来省略它。

但是执行此规则将不允许rese7FwDdvgfe匹配,但在您的示例数据中您确实希望匹配它,因此您可以将后视排除在模式之外。

^(?=[^a-zA-Z\s]*[a-zA-Z])(?=(?:[^\d\s]*\d|[^\s@$!%*#?&£]*[@$!%*#?&£]))[@$!%*#?&£a-zA-Z\d]{5,20}$

解释

  • ^字符串的开始
  • (?=[^a-zA-Z\s]*[a-zA-Z])断言大写或小写 az
  • (?=积极前瞻
    • (?:非捕获组
      • [^\d\s]*\d断言一个数字
      • |或者
      • [^\s@$!%*#?&£]*[@$!%*#?&£]断言一个特殊的字符
    • )关闭非捕获组
  • )关闭正向前瞻
  • [@$!%*#?&£a-zA-Z\d]{5,20}匹配所有允许的 5 - 20 次
  • $字符串结束

正则表达式演示


推荐阅读