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

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

#43

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


#44

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.


#45

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


#46

This worked for me:

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


#47

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.


#48

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.


#49

Thank you! This reply was key to my understanding