如何为用户名验证构建正则表达式?

时间:2016-05-02 03:39:57

标签: php regex username

我正在为具有以下约束的用户名验证构建PHP正则表达式:

  

- 长度必须为10-16个字符,包含字母,数字和至少一个特殊字符(*& ^ -_ $)的组合    - 不能以数字或特殊字符开头

更正:最后的SIX数字必须是月/日生日(MMYYYY format)。为了进一步验证用户名,月/日必须显示用户名超过18 - 如果不是,用户名将不会验证。提前感谢您的帮助!我已经坚持了一段时间。

2 个答案:

答案 0 :(得分:2)

解决方案

您可以使用以下正则表达式执行此操作:

/(?=^.{10,16}$)(?=.+?[*&^_$-])[a-z].+?[01]\d{3}$/i

Here's a demo with some unit tests.

解释

  • /分隔符
  • (?=^.{10,16}$)确保有10-16个字符,从头到尾
    • (?=启动了一个前瞻小组
    • ^字符串的开头
    • .{10,16}十到十六个字符
    • $字符串结尾
    • )结束了前瞻小组
  • (?=.+?[*&^_$-])确保集*&^_$-中至少有一个特殊字符,并且不是第一个
    • (?=启动了一个前瞻小组
    • .+?一个或多个字符,非贪婪
    • [*&^_$-]*&^_$-中的任何字符(请注意订单;您必须先将-放在最后或最后,或将其作为\-转义
    • )结束了前瞻小组
  • [a-z]以字母开头
  • .+?以非贪婪的方式匹配任何字符,并根据需要返回
  • [01]\d{3}匹配01,然后再匹配3个
  • $匹配字符串的结尾
  • /结算分隔符
  • i使匹配不区分大小写

关于正则表达式构造的一些注释

请注意,有多种有效的方法可以做到这一点。为了实现纯粹的效率,可以稍微简化上述解决方案,为处理器省去一些步骤。

但为了便于阅读,我喜欢使用上述内容。很清楚每个块,字符集或组的作用,使其可读和可维护。

/^[a-z](?=.*?[*&^_$-])[a-z0-9*&^_$-]{5,11}[01]\d{3}$这样的东西很难阅读和理解。如果您想允许17个字符的用户名怎么办?您必须做一堆数学运算才能确定应将{5,11}更改为{5,12}。或者,如果您决定允许角色#,则必须将其添加到两个位置(顺便说一句,这意味着正则表达式已经违反了DRY principle)。

奖金:为什么你的尝试失败

你在评论中说过你试过这个:

(?=^.{10,16}$)^[a-z][\d]*[_$^&*]?[a-z0-9]+

第一部分(?=^.{10,16}$)很好。 ^[a-z]也是如此。

[\d]* 匹配零个或多个数字;它与字母或特殊字符不匹配。因此,例如,a&a...将失败。

[_$^&*]?只匹配零个或一个特殊字符。这将允许带有 no 特殊字符的用户名通过,但会失败一个带有2个特殊字符的用户名。

[a-z0-9]+仅匹配这些字符,并且省略了最后四个字符必须为数字的要求。

您可能会发现the explanation on regex101.com of your regex有帮助。 (注意:我与该网站没有任何关系。)

答案 1 :(得分:0)

您可以使用此正则表达式:

^[a-zA-Z](?=.*[*&^_$-])[\w*&^$-]{5,11}[01]\d{3}$

正则表达分手:

^                  # Line start
[a-zA-Z]           # # match an alhpabet
(?=.*[*&^_$-])     # lookahead to ensure there is at least one special char
[\w*&^$-]{5,11}    # match 5 to 11 of allowed chars
[01]\d{3}          # match digits 0/1 followed by 3 digits
$                  # Line end

我使用了量词{5,11},因为一个char在开始时匹配,4个在最后匹配,从而从期望的{10,16}长度中取出5个位置。