Reuse Patterns Using Capture Groups - Can't pass certain tests

Reuse Patterns Using Capture Groups - Can't pass certain tests
0

#1

I’m not sure why I fail:
Your regex should reuse the capture group twice.
Your regex should have two spaces separating the three numbers.
Your regex should not match “42 42 42 42”.

In the console I get ["42 42 42", "42 "], which uses the capture group twice and has 2 spaces. What am I missing?

let repeatNum = "42 42 42 42";
let reRegex = /(\d+\s)\1\d+/; // Change this line
let result = reRegex.test(repeatNum);
console.log(repeatNum.match(reRegex));

#2

This line reads:

Return me a match if

  • \d+ — any number of digits
  • \s — are followed by a space
  • \1 – and is followed by the same previous match
  • \d+ — then followed by any number of digits

What you want is to match a group of 3 equal matches. So like

42, 42, 42
123456, 123456, 123456

// but not less
42, 42

// or more
42, 42, 42, 42

#3

But you don’t explain why I get that output I mention. Why since I get 2 spaces and I reuse the capture group twice, I fail those 2 at least…


#4

Because you’re not re-using the groups like you think you are.

Let’s look at this step by step. We start with “42 42 42 42”. I’ll place all the matches in a string array for clarity.

  • \d+
    • this matches groups of digits, no spaces
    • we get [ '42', '42', '42', '42' ]
  • \s
    • matches digits with just one 1 space following it
    • and we get [ '42 ', '42 ', '42 ' ]
    • if we stop here, we’d have 3 matches of your group [ '42 '] // #1
    • this is the group that gets repeated
  • \1
    • this repeats your capture group once wherever you place it
    • so you’re saying: repeat [ '42 ' ] once
    • now we get[ '42 42 ']
    • we only get one match because the required repeating pattern of [ '42 42 ' ] only happens once. The rest of the string looks like this [ '42 42' ]. The last ‘42’ has no space after it.
  • \d+
    • this matches any number of digits after repeating your match
    • so take my match of [ '42 42 ' ] and match if there’s a group of digits following
    • finally we have [ '42 42 42' ] // #2
    • we stop matching because the remaining string is [ '42' ] which doesn’t match any requirement

The reason you’re getting confused is because you think it’s repeating the capture group twice. But the numeric reference \1 only repeats in the location where it is placed.

In the console, you’re getting the result of the match, followed by the capture group that produced this result

["42 42 42", "42 "]
Index 0 is the match, which fits what we see at #2, and index 1 is the capture group which we see in #1

So you’re returning a match, while the test expects you to not match. There’s a clue in this line as to what to match and repeat

Your regex should have two spaces separating the three numbers.

and this one

Your regex should reuse the capture group twice.

Find a way to satisfy these specs while using \1 twice.

Hope that clears it up some more. Let me know if there’s something I didn’t explain clearly.


#5

Thanks @JM-Mendez for all your help.

These clues:

Your regex should have two spaces separating the three numbers.
Your regex should reuse the capture group twice.

suggest to me (\d+)\s\1\s\1 or (\d+)\s\1\s\1$, both which pass all the tests except 42 42 42 42. In both of these regex’s the number is repeated three times, the capture group is reused twice, and there are two spaces.

I’m at a loss for what more options I can try. I’ve used the regexr.com website and have tried over a dozen possibilities.


#6

You are really close. The reason it won’t pass the string ‘42 42 42 42’ is because you anchored the match to the end, so it’s capturing the last 3 groups. Regex is greedy, so it will try to match as a many times as it can.

You have to anchor both sides. This is the only way to match a very specific repetitive pattern, unless you write a super complex regex. But then it’d probably be better to just loop over the matches.


#7

Oh! I just solved it after looking at the next question, which explained capture groups a bit more. It helped me realize I can anchor the capture groups on both sides, just like you said–and it finally passed!

I’m sure your answer will help many others :slight_smile:


#8

On this note does anyone know why mine would not pass using two capture groups?

let reRegex = /^(\d+)(\s)\1\2\1$/; // Change this line

I ended up having to replace the second with a space (i.e. \2\ = \s) and it passed. Just curious.


#9

Which tests did it not pass?


#10

The first two:

Your regex should use the shorthand character class for digits.
Your regex should reuse the capture group twice.


#11

thank you so much for your explanation! this is exactly what I am looking for : )


#12
  1. I think they are testing for a specific pattern
  2. your regex is only returning 2 matches, when the requirements expect 3

#13

This code passes the test but does not work at RegExr.


let repeatNum = "42 42 42";
let reRegex = /(^\d{0,})\s\1\s\1$/; // Change this line
let result = reRegex.test(repeatNum);

And this passes at RegExr but not in FCC.


let repeatNum = "42 42 42";
let reRegex = /(\d+)(\s)\1\2\d+/; // Change this line
let result = reRegex.test(repeatNum);

#14

I’m not seeing any errors with this on regexr. Is there any specific error you get?

This passes on regexr because you are returning the correct format 'digits-space` twice. But one of the specs of the test is:

Your regex should reuse the capture group twice

And you only reused it once.


#15

Thanks for your help.


#16

Why is the first option working for you? It seems like its capture case is searching for non-digits. (^\d{0,}).