【问题标题】:How to include special chars in this regex如何在此正则表达式中包含特殊字符
【发布时间】:2013-09-04 21:41:42
【问题描述】:

首先我是一个正则表达式的菜鸟,所以这可能会进一步优化,如果是这样,请告诉我该怎么做。不管怎样,看了几篇关于正则表达式的文章后,我写了一个小正则表达式来满足我的密码匹配需求:

(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(^[A-Z]+[a-z0-9]).{8,20}

我要做的是:它必须以大写字母开头,必须包含小写字母,必须至少包含一个数字,必须至少包含一个特殊字符,并且长度必须在 8-20 个字符之间。 以上以某种方式有效,但它不会强制使用特殊字符(。似乎匹配任何字符,但我不知道如何将它与正前瞻一起使用)并且最小长度似乎是 10 而不是 8。我在做什么错了吗?

PS:我正在使用http://gskinner.com/RegExr/ 进行测试。

【问题讨论】:

  • 您希望允许哪些特殊字符?
  • (?=.*[A-Z]) 检查您是否知道密码必须以大写字母开头(即您有^[A-Z]+[a-z0-9])有什么意义?
  • 哦,愚蠢的密码:> 只需要 12 个字符(可能限制为 100 个),其他的就随便了。
  • 正则表达式的方言大约有一百万种,您为什么语言或工具编写正则表达式?
  • 但是是的,. 在大多数正则表达式方言 except 中,当它被转义 \. 或在字符类 @987654327 中时,将匹配任何东西 @(有时也有一些行尾警告)。

标签: regex


【解决方案1】:

让我们去掉断言,只看你的基本模式:

(^[A-Z]+[a-z0-9]).{8,20}

这将匹配一个或多个大写拉丁字母,后跟一个小写拉丁字母或十进制数字,然后是 8 到 20 个任意字符。所以是的,这至少需要 10 个字符,但它没有匹配的最大字符数(例如,它允许字符串开头有 100 个大写字母)。此外,由于没有结束锚点 ($),此模式将允许匹配的子字符串后面的任何尾随字符。

我推荐这样的模式:

^(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$])[A-Z]+[A-Za-z0-9!@#$]{7,19}$

!@#$ 是您想要允许的任何特殊字符的占位符。必要时不要忘记转义特殊字符(\]^ 在字符类的开头,- 在中间)。


使用POSIX character classes,它可能看起来像这样:

^(?=.*[:lower:])(?=.*[:digit:])(?=.*[:punct:])[:upper:]+[[:alnum:][:punct:]]{7,19}$

或者使用Unicode character classes,它可能看起来像这样:

^(?=.*[\p{Ll}])(?=.*\d)(?=.*[\p{P}\p{S}])[\p{Lu}]+[\p{L}\d\p{P}\p{S}]{7,19}$

注意:每个都考虑一组不同的“特殊字符”,因此它们与第一个模式不同。

【讨论】:

  • 可能值得补充的是,在国际环境中,使用 POSIX 字符类 [:upper:]、[:lower:]、[:alpha:]、[:digit:] 会更明智, 和 [:alphanum:] 视情况而定。使该模式适用于其他语言,并使正则表达式更具可读性,这是一种令人愉快的副作用。
  • @ConspicuousCompiler 我同意这不是最本地化的解决方案,我自己可能不会使用它。我个人更喜欢 unicode 类而不是 POSIX,虽然我不确定这是否使它更兼容,因为它需要引擎支持 POSIX / Unicode 字符类。无论如何,我都为两者提供了一个经过调整的版本。
【解决方案2】:

以下应该有效:

^(?=.*[a-z])(?=.*[0-9])(?=.*[^a-zA-Z0-9])[A-Z].{7,19}$

我删除了(?=.*[A-Z]),因为您必须以大写字符开头的要求已经涵盖了这一点。我为特殊字符添加了(?=.*[^a-zA-Z0-9]),这只会在至少有一个字符不是字母或数字的情况下匹配。我还稍微调整了长度检查,这里的第一步是删除[A-Z] 之后的+,以便我们知道到目前为止已经匹配了一个字符,然后将.{8,20} 更改为.{7,19} (如果我们已经匹配了 1 个字符,我们只能再匹配 7 到 19 个字符)。

【讨论】:

    【解决方案3】:

    好吧,如果我有这样的要求,我会这样写——除了绝对不可能或不切实际的情况,我更喜欢分解复杂的正则表达式。请注意,这是特定于英语的,因此 Unicode 或 POSIX 字符类(如果支持)可能更有意义:

    /^[A-Z]/ && /[a-z]/ && /[1-9]/ && /[whatever special]/ && ofCorrectLength(x)
    

    也就是说,我会避免尝试一次合并所有规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2016-07-21
      • 1970-01-01
      • 2016-12-12
      • 1970-01-01
      相关资源
      最近更新 更多