5

我正在尝试创建一个regex来验证用户名,该用户名应与以下内容匹配:

  • 只允许一个特殊字符(._-),并且不能在字符串的极值处
  • 第一个字符不能是数字
  • 允许的所有其他字符都是字母和数字
  • 总长度应在 3 到 20 个字符之间

这是针对 HTML5 验证模式的,所以很遗憾它必须是一个大的正则表达式。

到目前为止,这就是我所拥有的:

^(?=(?![0-9])[A-Za-z0-9]+[._-]?[A-Za-z0-9]+).{3,20}

但是积极的前瞻可以重复多次,允许不止一个特殊字符,这不是我想要的。我不知道如何纠正。

4

2 回答 2

16

您应该将您的正则表达式分成两部分(而不是两个表达式!)以使您的生活更轻松:

首先,匹配用户名需要的格式: ^[a-zA-Z][a-zA-Z0-9]*[._-]?[a-zA-Z0-9]+$

现在,我们只需要验证长度约束。为了不弄乱已经找到的模式,您可以使用仅验证字符数的非消耗匹配(它实际上是为您的正则表达式创建and模式的黑客):(?=^.{3,20}$)

如果匹配长度约束,正则表达式只会尝试匹配有效格式。它是非消耗的,所以它成功后,引擎仍然在字符串的开头。

所以,一起:

 (?=^.{3,20}$)^[a-zA-Z][a-zA-Z0-9]*[._-]?[a-zA-Z0-9]+$

正则表达式可视化

调试器演示

于 2015-02-08T10:52:40.463 回答
0

我认为您需要使用?而不是+,因此特殊字符仅匹配一次或不匹配。

^(?=(?![0-9])?[A-Za-z0-9]?[._-]?[A-Za-z0-9]+).{3,20}

于 2015-02-08T10:46:54.730 回答