用户名不能包含重复的下划线或句点

Spa*_*Kat 6 regex

我一直在努力应对这些艰难的事情.我记得一位讲师告诉我们所有人,如果你有一个问题需要你使用正则表达式解决它,你实际上现在有两个问题.

嗯,我当然同意这一点.正则表达式是我们不经常使用的东西,但是当我们这样做时,就像阅读一些外来语言一样(对我而言)...我想我会决定拿到这本书并进一步阅读.

我面临的挑战是,我需要根据以下标准验证用户名:

  1. 可以包含上下字母
  2. 可以包含数字
  3. 可以包含句点(.)和下划线(_)
  4. 句号和下划线不能连续,即__ ..不允许但._._有效.
  5. 最多20个字符

到目前为止,我有以下内容:^[a-zA-Z_.]{0,20}$但当然它允许重复下划线和句号.

现在,我可能做错了,从有效字符集和最大长度开始.我一直在尝试(不成功)创建一些环视或后视或其他任何搜索无效的句点重复(.)和下划线(_)不确定将此要求分解为正则表达式解决方案的方法或方法是什么.

任何人都可以协助推荐/替代方法或指出我正确的方向吗?

sp0*_*00m 9

这是你需要的那个:

^(?:[a-zA-Z0-9]|([._])(?!\1)){5,20}$
Run Code Online (Sandbox Code Playgroud)

正则表达式可视化

在Debuggex上实时编辑

您可以在这里演示它匹配的内容.


"要么是一个alphanum char([a-zA-Z0-9]),要么是(|)一个点或一个下划线([._]),但是它本身不是(),而是(?!\1)5到20次({5,20})."

  1. (?:X)简单地说就是一个非捕获组,即你不能引用它以后使用\1,$1?1语法.

  2. (?!X)被称为负向前瞻,即字面意思是"其中没有跟随X".

  3. \1是指第一个捕获组.由于第一组(?:...){5,20}已被设置为非捕获(参见#1),因此第一个捕获组是([._]).

  4. {X,Y}表示从X到Y次,您可以根据需要进行更改.

  • 这可能是最快的解决方案. (2认同)

Tim*_*ker 6

您可以使用两个负前瞻断言:

^(?!.*__)(?!.*\.\.)[0-9a-zA-Z_.]{0,20}$ 
Run Code Online (Sandbox Code Playgroud)

说明:

(?!  # Assert that it's impossible to match the following regex here:
 .*  # Any number of characters
 __  # followed by two underscores in a row
)    # End of lookahead
Run Code Online (Sandbox Code Playgroud)

根据您的要求和正则表达式引擎,您可以替换[0-9A-Za-z_.][\w.].

@ sp00n提出了一个很好的观点:您可以将前瞻断言合并为一个:

^(?!.*(?:__|\.\.))[0-9a-zA-Z_.]{0,20}$
Run Code Online (Sandbox Code Playgroud)

这可能会更有效率,但有点难以阅读.

  • 为什么不使用带有OR的单个负向前瞻?你的原则是整个输入3次. (2认同)

nne*_*neo 6

不要试图把它推到一个正则表达式.您的单个正则表达式适用于除#4之外的所有条件.要执行#4,只需执行与无效用户名匹配的正则表达式,如果匹配则拒绝用户名.例如(伪代码):

if username.matches("^[a-zA-Z_.]{0,20}$") and !username.matches("__|\\.\\.") {
    /* accept username */
}
Run Code Online (Sandbox Code Playgroud)