Regex Solution Not Valid... Why? From: "Regular Expressions: Restrict Possible Usernames"

I use Repl.it to check my code and the following code appears to work, however, when plugging this code into the interface at Regular Expressions: Restrict Possible Usernames, the solution is not valid.

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

Any thoughts to why? Thanks in advance.

(for reference for solutions that do work: Continuing the discussion from freeCodeCamp Challenge Guide: Restrict Possible Usernames: )

let username = "JackOfAllTrades";
let userCheck = /^[a-z][\d|a-z][\d|a-z]*$/i;
let result = userCheck.test(username);

Code Explanation

  1. /^[a-z] = ‘/’ begins the regex, ‘^’ anchors first character, first character ‘[a-z]’ must be letter character a-z.
  2. [\d|a-z] = the constraints of second character ‘[]’ are number ‘\d’ 0-9 OR ‘|’ letter character ‘a-z
  3. [\d|a-z]*$ = the constraints of third character ‘[]’ are number ‘\d’ 0-9 OR ‘|’ letter character ‘a-z’ that can occur zero or more times ‘*’ and are is anchored exclusively to the end of the string ‘$
  4. /i = ‘/’ ends the regex matching, and ‘i’ indicates the regex is not case sensitive
2 Likes

This part allows your regex to incorrectly match “A1”. The “A” is matched with the ^[a-z] (and the fact the the i flag is used. The 1 is matched next due to the [\d|a-z]. And since [\d|a-z]* matches zero or more numbers or the letters a-z, the zero part of it is matched, so you end up allowing “A1” incorrectly.

3 Likes

Thanks RandellDawson, clear description to what went wrong. Much appreciated
*4) Usernames have to be at least two characters long. A two-character username can only use alphabet letters as characters.

1 Like

an other issue is that usernames can have numbers only at the end, your code would accept A1A as an username

1 Like

Quite right, thank you for looking into this!
The solution I ended up with was:

let firstRegex = /^[a-z]([a-z]|[\d][\d]+)[a-z]*[\d]*$/i;

now I’m on to wrestling with Reuse Patterns Using Capture Groups… its a grand time haha, more questions to come.

Again Thank you for your response!

I still see an issue with your regex, as it will match something like c11cc1, as you have numbers in the middle.

@RandellDawson : do you think we need an other test to consider also this?

@nedious has basically hard coded his solution, if you will add just 1 more test, he will just include that exception. What you guys need is a function that will generate 500-1000 random usernames, so that’s impossible to hard code

@ilenia I have added a new test case (in PR #37769) which validates that a username like “c57bT3” should not pass.

2 Likes

Reading through your response @snigo helped identify a pattern of ‘hard coding’ I had been engaging in. Grateful for you highlighting this, I was able to go back and rework my solution.

I believe the following is not ‘hard coded’

let userCheck = /^([a-z]+)([a-z]+|[0-9][0-9]+)$/i; // Change this line

More thanks to @RandellDawson and @ilenia for investing time in this thread! I learned something new

How about this one: let userCheck = /(^[A-Za-z]{2,}\d*$)|^[A-Za-z]+\d{2,}$/;
?

2 Likes

Let’s define “hard-coded”, so it doesn’t offend anyone:
Hard-coded solution is a solution aimed towards passing tests and not solving a problem

If we stick to this definition then your code is still hardcoded, I’m afraid :slight_smile:

userCheck.test('nedious1');

This was what I came up with, what do you think? I really struggled until I remembered

the or operator
let userCheck = /^\D+\D\d*$|^\D\d\d$/;

1 Like

Hey @monicaparrillo,

your solution has one obvious problem: \D means [^0-9] which is a lot of characters, where you only supposed to use alphabet letters.

Also, I seems that userCheck.test('A007'); will not pass in your case

1 Like

Oh jeez, yes in the light of day I remember there are characters that exist besides letters and numbers (+, =, \ , ?..etc) As those weren’t part of the test cases I didn’t even consider them!

You’re correct as well that ‘A007’ fails, I will give another shot. Thank you for the feedback I am really struggling with regex.

Anyone that’s struggling, I find this reference sheet useful:

6 Likes

I came up with a similar solution as DetlefDmann. Can anyone explain why this doesn’t work? Thank you!!

Here is mine:
/^[a-z][0-9]{2,} | ^[a-z][a-z]+\d*$/i;


Right after I posted I figured it out:

/^[a-z][0-9]{2,}$ | ^[a-z][a-z]+\d*$/i;

In the first condition I was forgetting to check that the numbers were the final characters.

1 Like

Your code has been blurred out to avoid spoiling a full working solution for other campers who may not yet want to see a complete solution. In the future, if you post a full passing solution to a challenge and have questions about it, please surround it with [spoiler] and [/spoiler] tags on the line above and below your solution code.

Thank you.

1 Like

Thank you! I totally forgot to do that.

Solution 2 provided does not pass the username A2g .The instruction mentions - “2) The only numbers in the username have to be at the end. There can be zero or more of them at the end. Username cannot start with the number.” It does not disqualify usernames with numbers in between. How then is the Solution 2 one of the possible solutions?

do you mean the solution in the guide?

the solutions may refer to a previous version of the challenge.

if you confirm you mean the guild I will take a look and see how can I update it