Reuse Patterns Using Capture Groups - Give me more examples please

I’m struggling to understand this concept and googling for examples of capture groups just leads to finding complicated expressions making it harder.

Can anyone just give some very basic examples of using capture groups including the \number stuff?

My limited understanding with the code writen:

(\d+)\s look for (at least one) numbers until you find a white space
Again, repeat (\d+)\s as requested by challenge
Then repeat three times is denoted by \3

I think the wording of the question is confusing me.

Your code so far





let repeatNum = "42 42 42";
let reRegex = /(\d+)\s(\d+)\s\3/;

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/regular-expressions/reuse-patterns-using-capture-groups/

It is confusing. It took me quite a while to wrap my head around the concept of capture groups, but if you have patience, it does make sense.

In your regex:
let reRegex = /(\d+)\s(\d+)\s\3/;

…you start out right: the first parenthesis indicates a capture group. Later on IN THAT SAME REGEX, you can refer to that first capture group by \1. The second set of parenthesis, however, are creating a second capture group, which you could refer to as \2.

Instead, where you want to have three instances of the same thing, try something like:

let reRegex = /(\d+)\s\1\s\1/;

This indicates a capture group, whitespace, another instance of the same capture group, whitespace, and a third instance of that same capture group.

It actually took a LONG stretch on a regex tester for me to grok this concept. it’s not easy.

Of course, I haven’t GIVEN you the answer. It will still fail, there are a couple more things you want to be watching for in that regex string, but that will take care of your capture group question…

6 Likes

Could you explain why this code is not finished

let reRegex = /(\d+)\s\1\s\1/;

It has two whitespaces and started and finished from queried pattern. Why we need ^ and $?

Sure, i think i can explain. If you try that pattern on a regex tester, it will accept 42 42 42 - as it should. But it will also accept 42 42 42 42 - which you don’t want.

By placing the caret and dollar sign, you are telling the regex “exactly three times, with nothing else.” It’s a pretty tight limitation.

3 Likes

Curious why does it also accept 42 42 42 42 if you specify the capture group and blank space for a pattern of 3 like in the previous post of
let reRegex = /(\d+)\s\1\s\1/;
Thank you

Because your given regex doesn’t limit it, by indicating that the string CAN ONLY.CONTAIN three numbers, and two whitespace. The string must begin and end with the number - how could your regex indicate that?

Thank you for the reply and I believe I understand now. I was missing the fact that without the opening ^ and ending $ the string is considered a match once the 3 numbers and 2 spaces are matched even if additional characters/numbers precede and proceed the match criteria, again without the ^ and $. Thanks again for the explanation.

2 Likes

The caret (^) can be read as “a string that starts with…”, and the ending dollar sign ($) can be read as “… at the end of the string”. If you have the multi-line flag on your regex (so /...your regex here ... /gm – the g indicates global, and the m indicates multiple lines), it will allow for something like:

42 42 42
red cheese dogs
100 100 100

… and return two matches: the 42 42 42 and the 100 100 100. If we were to add a line 75 75 75 75, that would NOT match, as there are not exactly three instances of our capture group.

Without the multi-line flag, it would be useful to check, for example, a single text input. The multi-line option is great for textareas, or longer blocks of text, which may contain newline characters. The $, in the multi-line case, is “before the newline or at the end of the string,” and the ^ is "immediately following a newline, or at the start of the string.

2 Likes

I’m curious about this answer. As it stands either the challenge is phrased incorrectly or the answer is incorrect.
For the given answer: /^(\d+)\s\1\s\1$/
it will correctly match the pattern 42 in the string “42 42 42”. However it fails on “21 42 42 42” as well as “42 42 42 21”.
The challenge doesn’t state that the repeated pattern must be the only pattern, it just says

> match numbers that are repeated only three times in a string, each separated by a space.

So, either the challenge is phrased incorrectly or the given answer is incorrect. What am I missing?

1 Like

Well, the code provided does assume the pattern matches exactly the contents of the line, and it passes the test suite so…

That said, you could theoretically do something using negative “lookaround” like so:

/(?<!\1).*(\d+)\s\1\s\1.*(?!\1)/g

In that, the capture group is the second parens, the first says “but not preceded by the capture group.” Sadly, most browsers get really con-fuddled by capture groups in lookaheads.

3 Likes