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.
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?
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.
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.
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.
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, ?:).
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.