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

时间:2013-08-03 11:39:40

标签: regex

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

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

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

  1. 可以包含字母,上下
  2. 可以包含数字
  3. 可以包含句点(.)和下划线(_
  4. 句号和下划线不能是连续的,即不允许__ ..,但._._有效。
  5. 总共最多20个字符
  6. 到目前为止,我有以下内容:^[a-zA-Z_.]{0,20}$但当然它允许重复下划线和句号。

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

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

3 个答案:

答案 0 :(得分:9)

这是你需要的那个:

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

Regular expression visualization

Edit live on Debuggex

您可以演示它匹配的内容here


“alphanum char([a-zA-Z0-9])或(|)一个点或一个下划线([._]),但它本身不会跟随({ {1}}),以及5到20次((?!\1))。“

  1. {5,20}只是非捕获组,即您之后无法使用(?:X)\1或{{ 1}}语法。

  2. $1被称为否定前瞻,即字面意思是“其后没有X”。

  3. ?1指的是第一个捕获组。由于第一组(?!X)已设置为非捕获(请参阅#1),因此第一个捕获组为\1

  4. (?:...){5,20}表示从X到Y次,您可以根据需要进行更改。

答案 1 :(得分:6)

您可以使用两个negative lookahead assertions

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

<强>说明:

(?!  # 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

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

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

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

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

答案 2 :(得分:6)

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

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