1

我想为具有以下条件的用户名实现正则表达式:

  1. 用户名将仅包含 az、AZ、0-9 和 -(连字符);

  2. 用户名不应仅包含数字或连字符,但只能包含字符;

  3. 第一个和最后一个字符不应该是连字符(可以是数字但不完全是数字);

  4. 此外,不应该有 2 个连字符背靠背;

  5. 最小字符数为 5,最大字符数为 25;

到目前为止,我已经尝试过这个正则表达式:

var filter = /(?=[a-zA-Z0-9-]{5,25}$)^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$/;

它正确地满足了条件 1、3、4 和 5。但它并不完全满足条件 2。在我的正则表达式中,它确保它不完全由连字符组成。但它确实只允许数字,它不应该。

谁能让我知道我哪里出错或需要做什么。正则表达式的解释将不胜感激。

4

3 回答 3

5

为了可维护性,这样的事情通常最好写成一系列测试而不是一个大测试。

var filter = function (username) {
    var allDigits = /^[0-9]+$/g,
        allHyphens = /^[-]+$/g, //doesn't need a character class, but I find it's more readable
        multiHyphens = /[-]+/g,
        startsWith = /^[A-Za-z0-9]{1}/,
        endsWith = /[A-Za-z0-9]{1}$/
        hasInvalidChars = /[^A-Za-z0-9-]/,
        meetsReqs = false;
    if (username.length >= 5 || username.length <= 25) { //ensure correct length
        meetsReqs = !allDigits.test(username);
        meetsReqs = meetsReqs && !allHyphens.test(username);
        meetsReqs = meetsReqs && !multiHyphens.test(username);
        meetsReqs = meetsReqs && !hasInvalidChars.test(username);
        meetsReqs = meetsReqs && startsWith.test(username);
        meetsReqs = meetsReqs && endsWith.test(username);
    }
    return meetsReqs;
};
于 2013-07-04T16:43:15.803 回答
3

您可以在开头添加一个否定的前瞻。我还将^锚点放在表达式的开头。

^(?![0-9]+$)(?=[a-zA-Z0-9-]{5,25}$)[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$
 ^^^^^^^^^^^

这可以防止匹配,^[0-9]+$换句话说,一个只有数字的字符串。

于 2013-07-04T16:27:44.290 回答
0

这似乎可以在我的计算机上进行快速测试:

^(?![^-]*--+)(?![0-9]+$)[a-zA-Z0-9][-a-zA-Z0-9]{3,23}[a-zA-Z0-9]$

解释

^(?![^-]*--+)  No double (or more) hyphens
(?![0-9]+$)    Digits only forbidden
[a-zA-Z0-9]    Starts with a-z A-Z or 0-9
[-a-zA-Z0-9]{3,23}  Three to 23 more characters, including hyphens
[a-zA-Z0-9]$    Ends with a-z A-Z or 0-9

所以这是 1 + (3 to 23) + 1 个字符,即 5 到 25。

于 2013-07-04T17:04:21.927 回答