Reuse-patterns-using-capture-groups specify number of patterns

Your code worked for me as well–thanks for your help!

I wonder if you could help to explain why the following would not work:
/^(\d+)\s\3/;

I think it’s because the above snippet would render true for number space numbernumbernumber. So, 42 424242 would work with that code, but 42 42 42 would not.

Conversely, using /^(\d+)\s\1\s\1$/ means that we have to start with a number, then a space, then the first number repeated, then another space, then end with the same number repeated. Hence, 42 42 42 works.

Am I getting this right?

\3 refers to the third capturing group. No such group exists. In the regular expression /(a)(b)(c)/

  • \1 refers to “a”
  • \2 refers to “b”
  • \3 refers to “c”

Thanks, that makes sense–so /( a )( b )( c )\1\2\3/ would then render true for abcabc.

Is there a RegEx expression to search for multiple repeats of the same capturing group? Or do you have to give the \1 every time you want to see ( a ) repeated?

I dont understand how this regEx work. I tried on RegExr.com and it does not work at all

Try it here: https://regex101.com/
It’s explained as follows-

^ asserts position at start of the string
1st Capturing Group (\d+)
\d+ matches a digit (equal to [0-9])

  • Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
    \s matches any whitespace character (equal to [\r\n\t\f\v ])
    \1 matches the same text as most recently matched by the 1st capturing group
    \s matches any whitespace character (equal to [\r\n\t\f\v ])
    \1 matches the same text as most recently matched by the 1st capturing group
    $ asserts position at the end of the string

I was just struggling with this, and I found the explanation pretty clear.
I think the key regarding that solution are the ^ and $.
I’ve tried to use {3} with no prevail.

1 Like

I understand all that clearly. I just did not understand why the regEx online tool did not found any matches using that expression above. Now I understand that the \1 is like a $1 a variable placement there. Before that. I was confused. FCC does not explain things very clear.

Hmm… perhaps I’m wrong, (I’ll be corrected if I am) but is actually not a variable?
The \1 is the second use of the capture group, and the $ is indicating the end of the string. Not sure is technically a variable.

Regarding your last statement- sometimes, yes.

I think that the FCC aim is always to do you yourself a deep research before coming here. Which I’m sure you did.
I got frustrated before because of how much time it took me to solve somethings, or not being able to solve them at all. But no more.
Specially something like a regex. I mean, is fine to understand the core, but most of the developers just learn to google the needed regex. I see no point in trying to learn every possible pattern. Yes to understand the underlying logic. Otherwise, you won’t be able to reach the solution at all.

Yes you are correct about FFC being a resource. I actually like to understand what I do before implementing it. I also spent too much time on this that my head almost blew out :slight_smile: . Now I am confident about regExp

1 Like

If you have a pattern, you can quantify it using a variety of symbols.

  • * means 0 or more
  • + means 1 or more
  • ? means 0 or 1

These are all just shorthand though. Here’s the key, and most important, way of quantifying a pattern:

{n,m}

What does this do? It matches between n and m times (inclusive). Let’s try to write out the previous shorthands:

? is {0,1}
* is {0,}
+ is {1,}

Wait, what’s that? I forgot to write my second number?

If you leave out m, it defaults to infinity. In other words, there is no upper limit when you leave it out.

But there’s one more trick. You can even shorten stuff like {3, 3}

{3,3} is {3}

Here’s how you’d use this stuff:

All mean the same:

colou?r
colou{0,1}
(color|colour)

That matched both British and American spellings of the word “colour”.

Now, to answer your question

Is there a RegEx expression to search for multiple repeats of the same capturing group? Or do you have to give the \1 every time you want to see ( a ) repeated?

It’s a good question! And you now know the tools to do exactly what you want. Let’s say that you want to match a \1 three times. Well, you could write that out in a few different ways:

All the same:

(\d)\1\1\1
(\d)\1{3,3}
(\d)\1{3}

The last one is the best because it’s both more readable and more concise. Let’s say, however, you want to match a space character too. And let’s say you actually want five \1s, with spaces in between. We have to special case the last sequence because it shouldn’t have a space at the end.

All the same:

(\d)\1\s\1\s\1\s\1\s\1
(\d)(\1\s){4,4}\1
(\d)(\1\s){4}\1

There’s actually another thing you can do. See, by grouping our pattern in brackets, we also assigned something to \2. We don;t want to do that! We can avoid this by putting a ? at the beggining. This tells the RegEx enginge that this isn’t a capturing group – but it should still group it together like parenthesis.

(\d)(?\1\s){4}\1

You should also be careful:

Two notes:

  • These quantifiers match the patterns freshly each time. This means that \d+ will match 543 (not just 111, 222, etc.)
  • If you use a capturing group and quantify it, the stored value is the last one matched. That means (\d)+\1 will match 1233, but not 1231.

If you have any more questions, please do ask.

1 Like

Thank you! It really helps to see the \1 working the same way as {x, y}.

This worked for me:

/^(\d+)\s\1\s\1$/

While I agree that this solution ( /^(\d+)\s\1\1$/ ) works for the given test cases, it won’t work for other test cases. This solution assumes that the repeating digits are pinned at the start and end of the string, therefore it works for the provided test cases such as “42 42 42” and properly fails for “42 42 42 42”.

Ideally, I would like to see a solution that would perform as follows:

“abc 21 21 21 def” = Match
“abc 21 21 21” = Match
“21 21 21 def” = Match
“abc 21 21 21 21 def” = No Match
“abc 21 21 21 21” = No Match
“21 21 21 21 def” = No Match

I feel like a solution for these test cases would be a more robust answere for the given problem statement:

Use capture groups in reRegex to match numbers that are repeated only three times in a string, each separated by a space.

I should add that I still haven’t come up with this answer so would be curious if anyone has any ideas.

I have come up with the regex /(\d+)(\s)\1\2\1/ that caters for both the cases such as;

42 42 42 52 => true
52 42 42 42 => true

but it does break that case in FCC that says it should not match 42 42 42 42.

Does it help? maybe we can improve it further from here.

Thank you! This reply was key to my understanding

Hey again. I post this question. I would like to know your opinion.

Thanks

This worked for me too though I don’t know why. This thing almost caused me sleepless nights :frowning:

This worked for me
^(\d+)(\s)\1\2\1$
From what I get:
^(\d) - start with a number
(\s) - then space
\1 - repeat first group, \2 - repeat second group, \1$ - repeat first group and make sure it’s the end of a string, so it matches 3 numbers in total

1 Like

I guess you already answered this but here you go the solution which I did not understand why use ^ and $.

let repeatNum = “42 42 42”;
let reRegex = /(\d*)\s\1\s\1/; // Change this line
let result = reRegex.test(repeatNum);

Hello your code works for me . Thanks