2015-07-02 34 views
4

我需要帮助为用户名建立一个正则表达式。稍微复杂的用户名正则表达式

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

下面是规则我必须遵循:

  • 第一个字符必须是小写字母,例如(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]$ 

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

+0

为什么你尝试在它'\ w'?当它应该是4或更多时,为什么你有'{1,}'? – ooga

+0

@ooga在一个阶段,我使用了4,然后试图让它在一个阶段使用单词,因此(\ w)和{1,},并尝试许多其他变体。因此我发布了不准确的正则表达式。道歉。 –

回答

5

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

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

注意,提前找一个数字(?=.*\d.*.$).*.$结尾,它确保整个输入的最后一位数字不会被计算为中间部分的数字(最后一个点使用最后一位数字,因此\d无法匹配)。

查看live demo与您的样品和一些边缘情况。

请参阅this external article了解四周的情况。

+0

有一个小错误:第一个字符应该是(a-z)。 –

+0

@kirmir哎呀 - 感谢您的 – Bohemian

+0

试图让我的头周围的“看aheads”,非常感谢!阅读这些以充分理解它。 –

1

如果你需要在一个单一的正则表达式中做到这一点,波希米亚有正确的答案。但是,根据您使用的语言/平台,运行通过if语句连接的多个正则表达式可能更干净更快。

if input.matches('^([a-z])([a-zA-Z0-9]{4,})([0-9])$')) 
    if (matches[1].matches('\d') && matches[1].matches('[a-zA-Z]') 
    return $true 

return $false 

如果您不能使用超前功能,也可以使用。

+0

在数据注释中使用ASP.NET MVC(C#),AFAIK必须使用单个语句。但是,谢谢你。 –

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),最后用数字或字符填充剩余的两个位置。

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

+0

有用,请记住这个方法,谢谢。总是有好的另一种方法。 –

+0

不要为这个问题用'\ w',因为它'_' – nhahtdh

+0

哎呦比赛,我想我设法避免这些陷阱,但我想不会。它也匹配数字,这不是我想要的。无论如何,固定。 – Xiyng

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