Cannot pass 2 tests in Restrict Possible Usernames

Tell us what’s happening:
I cannot pass the last two tests " Your regex should not match BadUs3rnam3" and " Your regex should match Z97"

What am I missing?

Your code so far


let username = "JackOfAllTrades";
let userCheck =  /[A-z][A-z]+[0-9]*/ //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/78.0.3904.97 Safari/537.36.

Challenge: Restrict Possible Usernames

Link to the challenge:
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/regular-expressions/restrict-possible-usernames

Hello Masker,

Regex can be a bit tricky. You haven’t fulfilled these two prompts:

  1. The only numbers in the username have to be at the end. There can be zero or more of them at the end.
  2. Usernames have to be at least two characters long. A two-character username can only use alphabet letters as characters.

The reason why you’re matching BadUs3rnam3 is because you’re not checking for numbers only at the end of the regex expression. So BadUs3 is matching because it has 2 or more letters and a digit. To fix that you would want to make sure that you’re starting your check at the beginning of the expression and that the expression only has numbers at the end. To do this, you’ll need to also make sure there’re no numbers in the middle and you can do that by starting your letter search at the beginning and your number search at the end. What symbols denote the beginning and end of a regular expression?

The reason why you aren’t matching Z97 is because your regular expression currently requires two letters as expressed by [A-z][A-z]. Instead you need to create a conditional because the only valid 2 length usernames are two letters, but there’s no two letter requirement for 3 length usernames. You can create conditionals using ([A-Z]+|[a-z]{5,}). This example says that you’re either searching for at a minimum of 1 capital letters or a minimum of 5 lowercase letters. You’ll have to adjust it to match the prompt’s parameters.

Good luck and hope this helps!

edit: replaced characters w/ letters for clarification

4 Likes

Thanks for the tips, nohjlau! I’ll let you know if it worked. The hints did not contain any explanation and wanted to avoid looking the solution.

I think I’m getting closer to the solution as I’ve taken care of Z97 by using $ at the end of the expression. Only BadUs3rnam3 are left and ^ is not doing anything when I put in the start string.

If you haven’t already, try using a regex checking tool like this one: https://www.regexpal.com/

You can put in your regex, put in your string to test, and it will immediately show you what parts match and what don’t. It’s so helpful! I use it every time I have to use regex. :sweat_smile:

2 Likes

show us your last code, let’s see

1 Like

Here it is: /^([A-Z]+|[a-z]{5,}$)/

your regex matches strings that start with one or more capital letters, OR contain only lower case letters in the number of 5 or more

the regex posted by @nohjlau was an example on how to use the OR operator, you can’t use that regex to solve this challenge

1 Like

Don’t worry, Regex is a struggle and it took me a looooong time to learn it and I still have trouble. Your original answer let userCheck = /[A-z][A-z]+[0-9]*/ was close. You just hadn’t fulfilled those two prompts. Now that you remember how to start the check at the beginning and finish at the end with ^$, your new regex expression should use your original expression with those added and if you run the test you’ll see that you only need to match Z97 to complete the challenge.

To complete the Z97 check you first have the [A-z] (since you must always start with a letter) and then you have to check whether you have one (or more) letters OR two (or more) numbers so that AA is valid and Z97 is valid.

I threw up a quick chart kind of visually explaining what I’m typing out. Essentially you got it, you just need to combine part of your expression into a an OR condition

4 Likes

This image is very useful and I can visualize the expression. At this point what’s stopping the test to pass is BadUs3rnam3. I have to look a way to not return numbers in the middle of the string. Here’s what I typed so far:

/^[A-z][\D]|[A-z][\d+$]/

I believe \D should return no digits and placing before | means it won’t show in the middle of the string. But seems it’s not working as I hoped. I’m continuing to revise the regex concepts until I solve this challenge.

We’re straying away from the mark now. Lets go back to your original expression: /[A-z][A-z]+[0-9]*/. If we add the ^ and $ we get /^[A-z][A-z]+[0-9]*$/ and when we test it we are only missing the Z97 match.
image

What happens if we try putting the OR operator around what we have after the first [A-z] because we know that the username must start with a letter? /^[A-z]([A-z]+|[0-9]*)$/ says we aren’t matching 3 tests:
image

Hmm. it seems like we’re going in the wrong direction… until we look at how we solved the Z97 and are getting two new problems that have 2 or less characters. Hmm. there’s a prompt that addresses this.

  1. Usernames have to be at least two characters long. A two-character username can only use alphabet letters as characters.

Ah! we are regex matching the [0-9]* because we only need 0 or more numbers. How can we change this expression ([A-z]+|[0-9]*) so that if our username has a length of 1 or 2, we check if they’re all letters and if it has a length of 3+ we check that they’re numbers?

So why aren’t we matching Oceans11 then? That’s because we are taking the [A-z]+ path and that expression doesn’t check to see if there are any digits at the end. How can we fix that?

3 Likes

So I have to change either one of them: either I have to modify [A-z]+ to include numbers at the end, or modify [0-9]* to include letters at the beginning. Maybe using the {} could be the key here.

My only accomplishment so far is not giving up and looking at the answer yet.

Edit: Just when I thought I finally found an answer, new errors are throwing at my face. This time it is don’t match A1 and J

^[A-z]([A-z]+|[0-9]*){2}$

1 Like

Just out of curiosity, what are you using to create those charts?

1 Like

@chuckadams This’s draw.io. I’m a fan because the drawings come up looking clean and it’s easy to use.

You are actually much much closer than you think. You didn’t use the {2} properly, but with a slight tweak you will have. If you look back at the second half of the original OR example I gave ([A-Z]+|[a-z]{5,}), we’re looking for a minimum of five lowercase letters [a-z]{5,}. Going back to your expression, if we replace the * with {2,} instead of adding it, we’ll have replaced 0 or more digits with 2 or more digits, which means because we start with [A-z] that this path ^[A-z][0-9]{2,}$ will only be taken if there are 3 or more characters which satisfies prompt 4.

We’re now left with matching Oceans11 so we need to work on the left path ^[A-z][A-z]+$
image
What can we add to ([A-z]+) to match those pesky digits? Here is our expression so far /^[A-z]([A-z]+|[0-9]{2})$/

2 Likes

I DID IT! I DID IT! I solved the challenge without looking up the solution!

To be honest, I don’t 100% understand why it worked this way. You can say that I used 50% logic and another 50% bruteforcing.

As for the answer, all I did is adding + before the $. My guess is, the dollar sign returns digits at the end of string, while the plus sign ensures that it gets more than one digits.

I’m so grateful to you that you take your time and patience to walk me around the problem. Thank you. And thanks to everyone who responded kindly.

3 Likes

please house, am on restricted possible username

this is my code /\D{2,}$\d*/i
but this is not passing for oceans11 and z97…please i need more explanation

This works ---->
/(^[a-z]+[a-z]+[0-9]*$)|(^[a-z]+.[0-9]+$)/

Has two regex expressions combined by an OR operator. Rounded paranthesis is necessary for each REGEX and no whitespace at the front and back of ‘|’ (OR) operator. I don’t know why. But it worked for me only after following this.

  1. (^[a-z]+[a-z]+[0-9]*$)
    1st regex checks if the string is starting with alphabets, has minimum 2 characters which are only alphabets and zero or more numbers at the end.

  2. (^[a-z]+.[0-9]+$)
    2nd Regex. If string has more than 2 characters, 1st one doesn’t match and comes down to the 2nd one because of the OR operator. This checks if the string has atleast 3 characters, starting with only alphabets and ending with(atleast one ) only numbers.

It is great that you solved the challenge, but instead of posting your full working solution, it is best to stay focused on answering the original poster’s question(s) and help guide them with hints and suggestions to solve their own issues with the challenge.

We are trying to cut back on the number of spoiler solutions found on the forum and instead focus on helping other campers with their questions and definitely not posting full working solutions.

Thank you for understanding.

3 Likes

Thank you, this chart help me a lot to grasp the logic between the relations (conditionals) in regex.

With new test cases its even more difficult to match all the cases. In fact some conditions are contradictory to the test cases. Like it shouldn’t match A1 but should match Z97 and require 2 characters too.
This was an honest solution until I added 9 to it XD.

/^[a-z9]{2,}\w\d*$/

now its more like hack.