Regular Expressions - Restrict Possible Usernames

Tell us what’s happening:
I don’t understand how I’m supposed to be able to match a two character username with only letters, while still being able to match a username with one letter, but multiple numbers.

Currently I have it checking that one option needs to only have letters from a - z when it’s a two character username. ^[a-z]{2,}$

or as an alternative, you can have a letter from a-z one or more times, and a digit from 0-9 that occurs zero or more times. ^[a-z]+\d*$

The other way I attempted to write it was this /^[a-z]{2,}\d*$/gi but that means Z97 doesn’t match. So how can I check that a two character username is only letters while a three character username can have only one letter and two numbers if there can be zero or more numbers?

Your code so far

let username = "JackOfAllTrades";
let userCheck = /^[a-z]{2,}$|^[a-z]+\d*$/gi; // Change this line
let result = userCheck.test(username);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36

Challenge: {{challengeTitle}} Regular Expressions - Restrict Possible Usernames

Link to the challenge:

You are close, but you have a few issues. I’ll get you started.

^[a-z]{2,}$

Tell me in plain English what that matches. Does it fulfill rule number 2?

Actually, now that I have thought about it some more, I guess you could leave this as is and just fix the second regex after the pipe. It’s probably not the way I would go, but it could be done. You might even need to add another pipe.

Sorry, I keep adding more info here. I hope I’m not being too confusing. The thing to keep in mind here for this first regex before the pipe is that while a two-character username can only use alphabet letters, that doesn’t mean a username that starts with two letters can’t have zero or more numbers after those two letters.

No worries, you’re fine. And what you’re saying about it being able to have two letters as well as numbers makes sense, but if I add the \d* it seems to take that as saying that the first two characters must always be letters which isn’t necessarily the case. I just keep going around it in my head, and when I change something it might check out for one string, but then another string that was previously matching would fail and it’s been cycling like this for me.

That’s why I figured if I can split it up and add the pipe, then maybe it will only take the first part for usernames with two letters, and then the rest it would default to the second half? At least that’s my attempt at thinking of a way to go about it.

Correct, for that regex. But then you have the second regex after the pipe to catch all the other possibilities.

Right, and I think I’m having issues where I can’t really think of a way to write it out that would pass for the second regex.

If I try this:

^[a-z]+\d*$

It won’t work because this alternative only requires one or more letters, and zero or more numbers. So it would pass single letters with no numbers, or it would also pass one letter and one number.

So basically my main issue is that I can’t figure out how to both limit it to a minimum of two characters that are letters only, while being able to have a minimum of one letter for other scenarios. The only way that could work in my mind would be if the numbers were limited to two or more which doesn’t match the challenge requirements.

Let’s look at the first regex again (I’m assuming you added the \d* to the end):

^[a-z]{2,}\d*$

This catches anything that starts with at least two letters and then has any amount of numbers after it (including no numbers). Some of the examples of what it will catch are:

aa
aaaaaaa
aa1111

Basically, it will catch almost everything, it is doing a ton of work here. What is the one valid username it won’t catch?

Okay so finally after some more forum searches, I finally figured out what I was doing wrong. I had to use capturing groups to split the regex.

let userCheck = /^[a-z]([a-z]+\d*|\d{2,})$/gi;

My logic in that it doesn’t make sense to be able to both accept only two letters while simultaneously being able to accept one letter and zero or more numbers wasn’t wrong, but I didn’t understand the correct way to split the regex up.

Without trying to give away the answer, if you pair capturing groups with the “or” operator, you can have the regex start out normally, and it will be able to branch off to be able to simultaneously match separate requirements.

So an example would be something like:

/peter (parker|pan)/

Where the capturing group will allow the regex match more than one option. So for my example it matches peter parker as well as peter pan. So in terms of the challenge, think about an overall common trait that the regex is always checking for, and then build your capturing group for the parts that differ. Hopefully that makes sense.

Also thanks for all the help!

This method is perfectly acceptable as well. You still could have done it with your original method though. You were very close. You just needed to make one change to the second regex. But if this method is easier for you to reason about then that’s the best method for you to use.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.