【问题标题】:Regular expression to validate username验证用户名的正则表达式
【发布时间】:2012-08-14 15:17:37
【问题描述】:

我正在尝试创建一个正则表达式来根据这些条件验证用户名:

  1. 只包含字母数字个字符, 下划线
  2. 下划线和点不能在结尾开始用户名(例如_username / username_ / .username / username.)。
  3. 下划线和点不能相邻(例如user_.name)。
  4. 下划线或点不能在一行中多次使用(例如user__name / user..name)。
  5. 字符数必须介于 8 到 20 之间。

这是我到目前为止所做的;听起来它强制执行所有标准规则但第 5 条规则。我不知道如何将第 5 条规则添加到此:

 ^[a-zA-Z0-9]+([._]?[a-zA-Z0-9]+)*$

【问题讨论】:

  • 不,每次只允许出现一次下划线或点
  • 但是 a_b_c_d_e 是有效的吧?
  • 是的,是的。我现在正在测试你的正则表达式,听起来工作正常:)
  • 如果用非点分隔,可以有多个点吗?即"A.B.C"(下划线的问题相同?)

标签: java php html regex perl


【解决方案1】:

我猜你必须在这里使用 Lookahead 表达式。 http://www.regular-expressions.info/lookaround.html

试试

^[a-zA-Z0-9](_(?!(\.|_))|\.(?!(_|\.))|[a-zA-Z0-9]){6,18}[a-zA-Z0-9]$

[a-zA-Z0-9] 一个字母数字 THEN (

_(?!\.) _ 后面没有 .或

\.(?!_) 一个。后面没有 _ OR

[a-zA-Z0-9] 一个字母数字)FOR

{6,18} 最少 6 到最多 18 次 THEN

[a-zA-Z0-9] 一个字母数字

(第一个字符是字母数字,然后是 6 到 18 个字符,最后一个字符是字母数字,6+2=8, 18+2=20)

【讨论】:

  • 试试:^[a-zA-Z0-9](_(?!(\.|_))|\.(?!(_|\.))|[a-zA-Z0-9]){6,18}[a-zA-Z0-9]$
  • 是的,这个有效。但是(_|\.) 表达式可以简化为[_.]
  • 很好,如果有人需要这样的 JS 正则表达式,这就是方法。它适用于所有浏览器,不像投票最多的答案是仅限 Chrome
【解决方案2】:

对不起,我从自己的库中生成了这个,它使用对 Dart/Javascript/Java/Python 有效的语法,但无论如何,这里是:

(?:^)(?:(?:[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKlMNOPQRSTUVWXYZ0123456789]){1,1})(?!(?:(?:(?:(?:_\.){1,1}))|(?:(?:(?:__){1,1}))|(?:(?:(?:\.\.){1,1}))))(?:(?:(?:(?:[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKlMNOPQRSTUVWXYZ0123456789._]){1,1})(?!(?:(?:(?:(?:_\.){1,1}))|(?:(?:(?:__){1,1}))|(?:(?:(?:\.\.){1,1}))))){6,18})(?:(?:[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKlMNOPQRSTUVWXYZ0123456789]){1,1})(?:$)

我的图书馆代码:

var alphaNumeric = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "l", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
var allValidCharacters = new List.from(alphaNumeric);
allValidCharacters.addAll([".", "_"]);

var invalidSequence = (r) => r
  .eitherString("_.")
  .orString("__")
  .orString("..");

var regex = new RegExpBuilder()
  .start()
  .exactly(1).from(alphaNumeric).notBehind(invalidSequence)
  .min(6).max(18).like((r) => r.exactly(1).from(allValidCharacters).notBehind(invalidSequence))
  .exactly(1).from(alphaNumeric)
  .end()
  .getRegExp();

我的图书馆:https://github.com/thebinarysearchtree/RegExpBuilder

【讨论】:

  • 是的,这很有趣:) 我可能只是做一个简单的正则表达式,然后使用 contains、startsWith 等......无论如何。 OK 将修复编号。
【解决方案3】:

对 Phillip 的回答稍作修改即可修复最新要求

^[a-zA-Z0-9]([._](?![._])|[a-zA-Z0-9]){6,18}[a-zA-Z0-9]$

【讨论】:

  • 这给字符限制规则带来了问题,给定规则{6,18} 它接受最少 8 个字符,而它必须接受 6 个字符,如果我让它 {4,18} 那么它将接受 6 个字符,而我已经定义了 4
【解决方案4】:

这个应该可以解决问题:

if (Regex.IsMatch(text, @"
    # Validate username with 5 constraints.
    ^                          # Anchor to start of string.
    # 1- only contains alphanumeric characters , underscore and dot.
    # 2- underscore and dot can't be at the end or start of username,
    # 3- underscore and dot can't come next to each other.
    # 4- each time just one occurrence of underscore or dot is valid.
    (?=[A-Za-z0-9]+(?:[_.][A-Za-z0-9]+)*$)
    # 5- number of characters must be between 8 to 20.
    [A-Za-z0-9_.]{8,20}        # Apply constraint 5.
    $                          # Anchor to end of string.
    ", RegexOptions.IgnorePatternWhitespace))
{
    // Successful match
} else {
    // Match attempt failed
} 

【讨论】:

    【解决方案5】:

    尽管我很喜欢正则表达式,但我认为可读性是有限度的

    所以我建议

    new Regex("^[a-z._]+$", RegexOptions.IgnoreCase).IsMatch(username) &&
    !username.StartsWith(".") &&
    !username.StartsWith("_") &&
    !username.EndsWith(".") &&
    !username.EndsWith("_") &&
    !username.Contains("..") &&
    !username.Contains("__") &&
    !username.Contains("._") &&
    !username.Contains("_.");
    

    比较长,但不需要维护者打开 expresso 即可理解。

    当然你可以评论一个很长的正则表达式,但是读过它的人必须依赖信任......

    【讨论】:

      【解决方案6】:
      ^(?=.{8,20}$)(?![_.])(?!.*[_.]{2})[a-zA-Z0-9._]+(?<![_.])$
       └─────┬────┘└───┬──┘└─────┬─────┘└─────┬─────┘ └───┬───┘
             │         │         │            │           no _ or . at the end
             │         │         │            │
             │         │         │            allowed characters
             │         │         │
             │         │         no __ or _. or ._ or .. inside
             │         │
             │         no _ or . at the beginning
             │
             username is 8-20 characters long
      

      如果您的浏览器由于缺乏负面的后向支持而引发错误,请使用以下替代模式:

      ^(?=[a-zA-Z0-9._]{8,20}$)(?!.*[_.]{2})[^_.].*[^_.]$
      

      【讨论】:

      • @ridgerunner - 我相信这种方式很容易阅读和移植到代码。
      • @vigneshkumar - 含义相同,但[a-zA-Z0-9._] 易于阅读和理解
      • (?&lt;![_.])$ 中的&lt; 对我造成“无效正则表达式”的解析错误
      • @JacksonLenhart - 您使用什么正则表达式引擎和编程语言?请注意,这个问题被标记为asp.net 标签,虽然答案对大多数其他语言和引擎都有效,但并非所有都支持负前瞻和后瞻零长度断言。
      • 请注意,这个正则表达式会导致 Angular 应用在​​ IOS 设备和 Firefox 浏览器上崩溃。
      【解决方案7】:

      ^[a-z0-9_-]{3,15}$

      ^ # 行首

      [a-z0-9_-] # 匹配列表中的字符和符号,a-z,0-9,下划线,连字符

      {3,15} # 长度至少为 3 个字符,最大长度为 15

      $ # 行尾

      【讨论】:

        【解决方案8】:
        private static final Scanner scan = new Scanner(System.in);
        
        public static void main(String[] args) {
            int n = Integer.parseInt(scan.nextLine());
            while (n-- != 0) {
                String userName = scan.nextLine();
                String regularExpression = "^[[A-Z]|[a-z]][[A-Z]|[a-z]|\\d|[_]]{7,29}$";
                if (userName.matches(regularExpression)) {
                    System.out.println("Valid");
                } else {
                    System.out.println("Invalid");
                }
            }
        }
        

        【讨论】:

          【解决方案9】:
          ^(?=.{4,20}$)(?:[a-zA-Z\d]+(?:(?:\.|-|_)[a-zA-Z\d])*)+$
          

          您可以测试正则表达式here

          【讨论】:

          • 这是允许在开头和结尾的下划线,这是不想要的。
          • 它也匹配只包含下划线的无限长字符串。
          • @Toto,我修好了。
          • 工作正常,但允许- 字符,我在这里做了一些调整:^(?=.{4,20}$)(?:[a-zA-Z\d]+(?:[._][a-zA-Z\d])*)+$ 为我修复它,感谢代码@FrEqDe
          【解决方案10】:
          function isUserName(val){
              let regUser=/^[a-zA-Z0-9](_(?!(\.|_))|\.(?!(_|\.))|[a-zA-Z0-9]){6,18}[a-zA-Z0-9]$/;
              if(!regUser.test(val)){
                return 'Name can only use letters,numbers, minimum length is 8 characters';
              }
            }
          

          【讨论】:

            【解决方案11】:
            const regex = /^moe_(app|lab)[A-Za-z0-9]{3}$/;
            const str = `moe_app_baa`;
            let m;
            
            if ((m = regex.exec(str)) !== null) {
                // The result can be accessed through the `m`-variable.
                m.forEach((match, groupIndex) => {
                    console.log(`Found match, group ${groupIndex}: ${match}`);
                });
            }
            

            【讨论】:

            • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
            最近更新 更多