Why does this answer work for "Find Characters with Lazy Matching"?

After a small break from the JS curriculum, I came back today. I’m reading about the Lazy Matching but after trouble not passing with keeping the? within the regex. Here’s the challenge page:

Find Characters with Lazy Matching

I kept having issues implementing the ? so in my annoyance, I ripped out everything within the < and > and simply did this:

let myRegex = /< h1>/; // Change this line

***I put a space between < and h so it would show in the example/spoiler.

To my surprise, this answer worked. But why? I was under the impression that we are supposed to use the ? for lazy matching. I don’t believe my “solution” is correct in this instance.

If I should have done it a different way to really pass it, I need to know because how else will I properly use lazy matching?

To add to this, others are doubting the test results and the OP here has 2 working options:

https://forum.freecodecamp.org/t/correct-solution-find-characters-with-lazy-matching/206914

You are technically looking for <h1> so yes it would return a positive.

I guess the the question is, when do I use ??

By default, regex will try to match as much as possible when you are using quantifiers such as * and +. However, if these quantifiers are followed by ?, then you’re telling regex to be lazy, or to find the bare minimum to make your regular expression true.

So going back to the challenge, let’s see what they provide:

let text = "<h1>Winter is coming</h1>";
let myRegex = /<.*>/; // Change this line
let result = text.match(myRegex);

Now recall that that regex is greedy. It will find as many characters to fulfill its gluttony. So what it matches is practically the whole string, right? Afterall, the whole string matches what it’s looking for a <, then some stuff in between, and then ends with a >.

But what if we gave it a ? pill that suppressed its hunger? Well, that is done by the following (answer):

let text = "<h1>Winter is coming</h1>";
let myRegex = /<.*?>/; // Change this line
let result = text.match(myRegex);

Here we are telling the regex to match as few wildcard characters to match the regex statement. And since we don’t have a g (global) tag, we will only match the first one.

Why does /<h1>/ work? Because in this regex, you’re trying to find exactly that, no compromise. It will give the same output as the solution.

2 Likes

@zapcannon99 I see what you’re saying and good to know I was wrong in this instance :rofl:

So others (like in the 2nd link above) implemented h1 into their solution as well, but they utilized the ? within the < and >. Are their 2 solutions correct because they directly expressed h1 as well, or because they utilized the *? properly, despite outright saying h1?

I haven’t leveled up enough to feel comfortable suggesting an additional test in GitHub to this challenge of using lazy ? as a requirement and not directly using h1 in the solution.

Tagging @stubravi because you may be interested in understanding this better as well.

It would be the former. They directly expressed to regex that they want to find something that has <h1> and then some number of wildcards afterwards found lazily.

Here is a thought experiment for you. What if I changed the problem regex to start off as the following?

/<.+>/

How would you then approach it?

As for your suggestion for an additional test to test for a check for non-explicit search for h1 is warranted. They should add it.

Let me know if you want me to just explain it away.

@zapcannon99 I’m not sure yet but let me look around the curriculum to refresh myself again with +. It’s currently offline (not sure why - probably maintenance). It logged me out and I can’t log back in just yet.

+ is used to match 1 or more of the preceding character.

Also, dunno if you’ve used this yet, but if you wanna play around with regex, try using https://regexr.com/

Okay, so we have a wildcard (.) and the + that is used to check for repeated characters. In our case for the < h1> is repeated in this challenge.

I would initially want to write /<.h1+>/ because in this challenge regarding the +, it puts the “s” from Mississippi in like this: /s+/g; as a passing solution

But if I do /<.h1+>/, wouldn’t I need to add global to it in order to get it to check the whole thing? Like this:

/<.h1+>/g;

However, we’re probably not trying to say outright h1 at all, right?

Going backwards, yes we are trying not to use h1 in our regex.

<.h1+> would not match what you think. It would match instead </h1>. Recall that + looks at the preceding character only. The only time it doesn’t is when the preceding character is a capture group or character set, which are () and [] respectively. The g tag only tells regex to find all the matches in the string. In addition, because you have a “.”, regex is looking for any character that follows the < and the h. Of course that’s not what we’re looking for.

When you were presented with the + in the challenge, yes s+ worked because you were specifically looking for repeats of s. In this case though, while not direct, the challenge this time wants you to see the effects of “?”. If i were to leave the regex as <.+>, the output would be the same as <.*>. Both quantifiers are greedy, they’ll match as much as they can to please their masters.

1 Like

The solution to the problem is similar to the one before. We want to limit the greed/workaholism of the quantifier symbols. That’s where the “?” comes in.

/<.+?>/

LOL you have given me something to really consider. There’s going to be a lot of outside source reading on JS in my future. But thank you for explaining it. :pineapple:

No problem. But as i said before, if you want to play regex, use https://regexr.com/. Not only can you play with it, but it gives a nice explanation of the regex you use to match. Take a minute and just look at the default example it uses.

Thanks for your explanation but how does regex identify whether h or h1 is the stopping point?

Which test are you referring to?

Does regex identify ‘

’ as a single string?

I’m assuming you referring to regex test with /<h1>/?

^(this one) Does the

tag identify as one single string with regex?