1

I am a newbie to regex and would like to create a regular expression to check usernames. These are the conditions:

  1. username must have between 4 and 20 characters
  2. username must not contain anything but letters a-z, digits 0-9 and special characters -._
  3. the special characters -._ must not be used successively in order to avoid confusion
  4. the username must not contain whitespaces

Examples

  • any.user.13 => valid
  • any..user13 => invalid (two dots successively)
  • anyuser => valid
  • any => invalid (too short)
  • anyuserthathasasupersuperlonglongname => invalid (too many characters)
  • any username => invalid because of the whitespace

I've tried to create my own regex and only got to the point where I specify the allowed characters:

[a-z0-9.-_]{4,20}

Unfortunately, it still matches a string if there's a whitespace in between and it's possible to have two special chars .-_ successively:

matches although whitespace and two dots successively

If anybody would be able to provide me with help on this issue, I would be extremely grateful. Please keep in mind that I'm a newbie on regex and still learning it. Therefore, an explanation of your regex would be great.

Thanks in advance :)

7
  • 1
    It is easiest if you provide a list of rules that you test against one by one. By using that approach, you can let the user know which rule (s)he has violated. Commented Mar 21, 2020 at 19:03
  • Well I‘ve opted for an approach that shows the user a message which specifies what could be the reason why the username is invalid. Using ifs for such checks is tedious... Commented Mar 21, 2020 at 19:07
  • Serious question: why are you putting all these restrictions on user names? Other than perhaps max length (which because of varchar should also not particularly matter), what real reasons do you have for all these restrictions? (e.g. your code for displaying user names shouldn't care. It might cut off usernames, but you should simply tell people that when they sign up. "picking a long username means people won't see the whole thing") Commented Mar 21, 2020 at 19:10
  • @Mike'Pomax'Kamermans because it's common practice to do so. For example, depending on the used font, users couldn't recognize that my__username has two underlines. Also, these rules prevent users from creating usernames like _________name________ Commented Mar 21, 2020 at 19:13
  • "Other people do it" is not a real reason. Tons of sites do this and it's a pain the ass as a user =) If someone wants the username __ then as long as your front end is clear about what is a username and what isn't, there is nothing wrong with that username, and it is important to remember that. Wanting to restrict it is fine, but a lot of "common practice" is based on technical limitations from decades ago, effectively none of which still apply if you're writing something new. Commented Mar 21, 2020 at 19:15

1 Answer 1

6

Sometimes writing a regular expression can be almost as challenging as finding a user name. But here you were quite close to make it work. I can point out three reasons why your attempt fails.

First of all, we need to match all of the input string, not just a part of it, because we don't want to ignore things like white spaces and other characters that appear in the input. For that, one will typically use the anchors ^ (match start) and $ (match end) respectively.

Another point is that we need to prevent two special characters to appear next to each other. This is best done with a negative lookahead.

Finally, I can see that the tool you are using to test your regex is adding the flags gmi, which is not what we want. Particularly, the i flag says that the regex should be case insensitive, so it should match capital letters like small ones. Remove that flag.

The final regex looks like this:

/^([a-z0-9]|[-._](?![-._])){4,20}$/

There is nothing really cryptic here, except maybe for the group [-._](?![-._]) which means any of -._ not followed by any of -._.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot for this answer :) I almost guessed that I should use negative lookahead but didn’t know how to achieve it 😂
I have been searching for the last 2 hours, you have saved my time. - Thanks a lot buddy @GOTO 0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.