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

Regex 用户名的正则表达式有点复杂,regex,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)
  • 中间的字符组只能是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]$
但是中间组不正确,我不知道如何执行“必须包含一个字母和一个数字”规则。

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

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

注意,一个数字<代码>(“.= *.D.*.$”)/<代码>的结尾在<代码> ** $ < /代码>中,它确保整个输入的最后一个数字不被计数为中间部分中的一个数字(最后一个点消耗最后一个数字,因此它不能用于<代码> \d>代码>匹配)。 请参阅您的示例和一些边缘案例


有关环顾四周的详细说明,请参见。

如果需要在单个正则表达式中执行此操作,Bohemian有正确的答案。但是,根据您使用的语言/平台的不同,运行由
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

如果您不能使用前瞻,也可以使用它。

如果您想要更直接、更原始的东西,您可以随时尝试

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


注意:我肯定不是说这是最好的解决方案,但它仍然是一个解决方案。

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

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

有一个小错误:第一个字符应该是(a-z)。试图让我的头周围'看aheads',非常感谢!!!阅读本文以完全理解它。为什么您的尝试中有一个
\w
?为什么你有
{1,}
而它应该是4或更多?@ooga在一个阶段我使用了一个4,然后试图让它在一个阶段处理单词,因此(\w)和{1,},并尝试了许多其他变体。因此我发布了不准确的正则表达式。抱歉。在ASP.NET MVC(C#)中使用此选项进行数据注释,AFAIK必须在单个语句中。但是谢谢你。很高兴知道,我会记下这个方法,谢谢。有另一种方法总是好的。不要用
\w
来解决这个问题,因为它符合
\uu
哎哟,我以为我成功地避免了那个陷阱,但我想不是。它还匹配了数字,这不是我想要的。不管怎样,修正了。