Order of Operations in Regular Expressions (solving a challenge)

Viewed 220

I am working on a problem from FreeCodeCamp that involves me developing a Regular Expression that meets these four requirements:

  • Usernames can only use alpha-numeric characters.
  • 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.
  • Username letters can be lowercase and uppercase.
  • Usernames have to be at least two characters long. A two-character username can only use alphabet letters as characters.

What I have decided on is /[a-z]/ig, which covers all of the test cases except for the following three:

  • Your regex should not match the string BadUs3rnam3
  • Your regex should match the string Z97
  • Your regex should not match the string c57bT3

What confuses me is that if I add numbers (\d) into my Regex then some of my simpler requirements ("Regex should match JACK") are now incorrect.

I was thinking that I could do something like:

/[a-b+?]*\d/

or this

/[a-b^0-9$]/

But that throws off things.

Can someone lend me a hand and explain how this might work?

1 Answers

The patterns that you tried do not match because:

  • The pattern [a-b+?]*\d matches optional chars a b + or ? followed by a single digit, which makes the digit mandatory and matches not allowed chars

  • The pattern [a-b^0-9$] only matches a single char a b ^ digit 0-9 or $ and also matches not allowed chars


You could either match 2 or more chars a-z followed by optional digits, or match a single char a-z followed by 2 or more digits.

^[a-z](?:[a-z]+\d*|\d{2,})$

Explanation

  • ^ Start of string
  • [a-z] Always start with a char a-z
  • (?: Non capture group
    • [a-z]+\d* Match 1 or more chars a-z and optional digits
    • | Or
    • \d{2,} Match 2 or more digits
  • ) Close non capture group
  • $ End of string

Regex demo

const regex = /^[a-z](?:[a-z]+\d*|\d{2,})$/i;
[
  "aa",
  "JACK",
  "abc",
  "ab1",
  "Z97",
  "BadUs3rnam3",
  "c57bT3",
  "a",
  "0",
  "01",
  "a1",
  "a",
  "ab1a"
].forEach(s => console.log(`${s} --> ${regex.test(s)}`));

Related