Provided solution for Checked Mixed Grouping of Characters

Tell us what’s happening:
I was able to pass this test with the solution I wrote below, but I find the solution provided in the help page ( /(Franklin|Eleanor).*Roosevelt/) to be a problematic example in that it allows for any number of characters in between the first and second word. While this doesn’t get in the way of demonstrating the concept, I do find it to be far too loose for the question’s criteria, which allows for only a middle name in between.

Your code so far


let myString = "Franklin D. Roosevelt";
let myRegex = /(Franklin |Eleanor )([^ ]* |)(Roosevelt)/; // Change this line
let result = myRegex.test(myString); // Change this line
// After passing the challenge experiment with myString and see how the grouping works

Your browser information:

User Agent is: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0.

Challenge: Check For Mixed Grouping of Characters

Link to the challenge:

Welcome, ryan.

Whist I do see what you are getting at, and would get behind someone changing the solution to something better practice, I would like to point out that your solution of [^ ]* matches the same number of regex elements as .*

That is to say, they both happen to match all-but-one. [^ ]* matches anything except spaces, and .* matches anything except for line terminators.

What would you suggest the guide solution be changed to?

2 Likes

I forget where this falls in the RegEx challenges. One thing to keep in mind is that we do want at least one solution to rely upon only the information in this challenge and the previous challenges.

That said, I do like where your head is at with this.

1 Like

Thank you for the greeting; it’s nice to be here :slight_smile:

Now, correct me if I’m wrong, as I am very, very new to Regex, but doesn’t matching everything but a space here solve the issue? It allows for exactly one word in between (Franklin |Eleanor ) and Roosevelt, which would only be realistically seen in the case of a middle name, whereas .* allows for any number of words.

Hello!

Thankfully, this challenge lies right near the end of the unit, with the only additional instruction being reusing capture groups and the replace function. I don’t believe that my solution falls outside of the scope of anything taught up to this particular challenge.

1 Like

Hello and welcome to the FCC community~!

I do understand your point, however… (this is not included in the test cases, but could be a “real-world” application for this concept)

The Regex you provided in your post would not account for two middle names, whereas the solution from the guide post does.
“Franklin John Smith Roosevelt” should pass as well. :slight_smile:

1 Like

Haha, you definitely got me there :pensive:

How about this?

/(Franklin |Eleanor )([A-Z]\S* )*(Roosevelt)/

This would only allow words in between the first and last name if they began with a capital letter, as they would in the case of middle names. It also more elegantly solves for a lack of a middle name than my prior solution, letting the * account for that instead of setting up an | condition.

Hey, that one works.
Regex101 advises against using the * on a capture group, though - it will only return the last match for that group instead of all the matches.

Hm, that is a pretty big issue. Their suggestion to enclose the middle caption group, plus its *, does work:

/(Franklin|Eleanor) (([A-Z]\S* )*)(Roosevelt)/

but is slightly inelegant in that it duplicates the final middle name, returning it both within the second capture group (the whole set of middle names) and the third (the final middle name). However, it does make the check work while capturing all the necessary data.

EDIT: This version cleanly omits the third capture group from the result, leaving one group with the first name, one with the middle name(s), and one with the last name. However, it uses syntax not covered in the curriculum (specifically, ?:).

/(Franklin|Eleanor) ((?:[A-Z]\S* )*)(Roosevelt)/

Yes, now this does work!

The only downside is that a (admittedly very quick) glance at the curriculum seems to show that capture groups aren’t explained until the next lesson.
The positive and negative lookahead lesson uses capture groups, but doesn’t explain them yet.

Haha, the curriculum titles are actually slightly misleading there. “Check For Mixed Grouping of Characters”, the lesson in question, is actually the lesson that explains how to use capture groups, while “Reuse Patterns Using Capture Groups”, the next lesson, covers reusing a capture group’s matched content using the \# syntax.

This is what I get for not reading. :sweat_smile:

Nice work! I’ll go ahead and propose your solution to the team! :slightly_smiling_face:

1 Like

I was able to pass the test with the following regexp:
/(Franklin|Eleanor)(\s[A-Z]\.){0,1}\sRoosevelt/
What do you think about it?