用户名略有复杂的正则表达式

时间:2015-07-02 22:54:44

标签: regex

我需要帮助为用户名构建正则表达式。

用户名有三个部分。第一个角色,中间组,最后一个角色。

以下是我必须遵循的规则:

  • 第一个字符必须是小写字母,例如(a-z)
  • 中间的字符组必须是4个或更多字符的字母和数字,例如(a-zA-Z0-9)
  • 中间组必须至少包含一个字母和一个数字
  • 最后一个字符必须是数字(0-9)

一些例子:

hTes38      (i.e. h Tes3 8)
j347k6      (i.e. j 347k 6)
atksde21D2  (i.e. a tksde21D 2)

这是我到目前为止所拥有的,几乎就在那里:

^[a-z][a-zA-Z0-9]\w{1,}[0-9]$

但是中间组不正确,我不知道如何强制执行'必须包含一个字母和一个数字'规则。

4 个答案:

答案 0 :(得分:5)

使用两个前瞻(一个用于字母,一个用于数字)断言中间部分至少有一个字母和一个数字:

^[a-z](?=.*[a-zA-Z])(?=.*\d.*.$)[a-zA-Z\d]{4,}\d$

请注意,数字(?=.*\d.*.$)的前瞻结束于.*.$,这可确保整个输入的最后一位数不会计入中间部分的数字(最后一个点消耗最后一位数字,因此\d无法匹配)。

请参阅live demo,了解您的样本和一些边缘情况。

有关环顾四周的详细说明,请参阅this external article

答案 1 :(得分:1)

如果您需要在单个正则表达式中执行此操作,波西米亚语有正确的答案。但是,根据您使用的语言/平台,运行由String getExistingFileEntry = "select * from test " + " where a = ? and b = ? and date < DATE_SUB(NOW(), INTERVAL 1 DAY)" + " order by id" + " limit 1"; 语句连接的多个正则表达式可能更清晰,更快捷。

if

如果你不能使用前瞻也行。

答案 2 :(得分:0)

如果你想要更直接和原始的东西,你总是可以尝试

\d[a-zA-Z][a-zA-Z0-9][a-zA-Z0-9]|\d[a-zA-Z0-9][a-zA-Z][a-zA-Z0-9]|
\d[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z]|[a-zA-Z]\d[a-zA-Z0-9][a-zA-Z0-9]|
[a-zA-Z0-9]\d[a-zA-Z][a-zA-Z0-9]|[a-zA-Z0-9]\d[a-zA-Z0-9][a-zA-Z]|
[a-zA-Z][a-zA-Z0-9]\d[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z]\d[a-zA-Z0-9]|
[a-zA-Z0-9][a-zA-Z0-9]\d[a-zA-Z]|[a-zA-Z][a-zA-Z0-9][a-zA-Z0-9]\d|
[a-zA-Z0-9][a-zA-Z][a-zA-Z0-9]\d|[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z]\d

中间部分。这似乎工作得很好但我没有用各种可能的组合测试它。

这背后的一般逻辑是交替数字的位置(从位置0到1到2到3),然后在剩余位置之间交替字符的位置(例如,如果数字位于位置1,字符交替从0到2到3),最后用数字或字符填充剩余的两个位置。

注意:我绝对不会声称这是最好的解决方案,但它仍然是一个解决方案。

答案 3 :(得分:0)

如果您想要清晰/简单,并且不限于单个正则表达式:

import re
s = "hTes38"
first, middle, last = s[0], s[1:-1], s[-1]
answer = bool(first.isalpha() and           # The first character must be a lower case letter
         last.isdigit() and                 # The last character must be a number
         len(middle) >= 4 and               # The middle group of characters must be 4 or more characters
         re.search("[a-zA-Z]", middle) and  # The middle group must contain at least one letter
         re.search(r"\d", middle) and       # AND one number
         re.match(r"[a-zA-Z\d]+$", middle)) # The middle group of characters must be letters and numbers only