skip to Main Content

i have the following conditions i’m trying to meet with a regex (for a username validation):

  • It must be between 6 and 30 characters long.
  • It cannot have two consecutive periods, hyphens,underscores, or @ symbols.
  • It must start and end with a letter or number.

i have the following which seems to work for the first two conditions, what would i add for the 3rd?

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

examples of valid strings:

[email protected]
1test-user
[email protected]
123456
asdfghjklpoiuytrewqasdfghjklpo
derghg$56

invalid

[email protected]
[email protected]!
test..user
test_.

2

Answers


  1. You can make a negative match, looking for invalid patterns. That makes it easy just combine with | anything you want.

    The only problem I don’t understand

    It cannot have two consecutive periods, hyphens,underscores, or @ symbols.

    whether it’s about the same symbol or any from the list.

    Anyway I hope you got the idea:

    /*
    It must be between 6 and 30 characters long.
    It cannot have two consecutive periods, hyphens,underscores, or @ symbols.
    It must start and end with a letter or number.
    */
    const valid = `
    [email protected]
    1test-user
    [email protected]
    12345
    asdfghjklpoiuytrewqasdfghjklpo
    `;
    
    const invalid = `
    user%name
    [email protected]
    [email protected]!
    test..user
    test_.
    `;
    
    // 12345 - seems invalid since less than 6 chars
    
    const names = ['ok_user@name', '[email protected]', 'asdf', 'asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasd', '_asdfs', '2asdf__']
    names.unshift(...valid.match(/S+/g));
    names.unshift(...invalid.match(/S+/g));
    
    names.forEach(str => 
      console.log(str, 'is valid:', !/^.{0,5}$|^.{31,}$|[-_.@]{2}|^[^a-z0-9]|[^[^a-z0-9]$|[^-w_.@]/.test(str))
    );
    Login or Signup to reply.
    1. Studying your regex, you seem to have a 4th condition: only allowed characters are alphanumerics,hyphens,underscores, or @ symbols.

    2. So, why don’t you combine what is at the start with what is at the end? First do your duplicate lookahead check (?!.*[_.@-]{2}) and then recognize that a string of 6-30 with alphanumerics at each end is the same as a 4-28 string sandwiched between alphanumerics [A-Z0-9][w.@-]{4,28}[A-Z0-9]. Put them together with:

    ^(?!.*[_.@-]{2})[A-Z0-9][w.@-]{4,28}[A-Z0-9]$

    If you assert the case insensitive flag (i), doesn’t that take care of it?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search