我正在为具有以下约束的用户名验证构建PHP正则表达式:
- 长度必须为10-16个字符,包含字母,数字和至少一个特殊字符(*& ^ -_ $)的组合 - 不能以数字或特殊字符开头
更正:最后的SIX数字必须是月/日生日(MMYYYY format
)。为了进一步验证用户名,月/日必须显示用户名超过18 - 如果不是,用户名将不会验证。提前感谢您的帮助!我已经坚持了一段时间。
答案 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}
匹配0
或1
,然后再匹配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个位置。