#392 · Parsing · Advanced · 140 XP · about 30 min
A web page is easier to style, and to read with a screen reader, when its tags are properly nested. Write well_nested(html) that returns True if the tags in html are properly nested and False if they are not.
What counts as a tag:
< followed by a name, then anything up to the next >, for example <a href="/">. A name is an English letter followed by any number of letters and digits, and case does not matter, so <DIV> is closed by </div>.> that sits within quotes (single or double) does not end the tag: <a title="x > y"> is one tag.> is / closes itself, like <span/> or <br />.</, a name and >, with nothing else, like </p>.br, hr, img, input, meta, link. A closing tag for one of them, such as </br>, is an error.<!-- starts a comment that ends at the next -->, and everything inside a comment is ignored.< that is not followed by a letter, by / and a letter, or by !-- is ordinary text, as in 3 < 5.The tags are properly nested when every closing tag closes the most recently opened tag that is still open, and every opened tag is closed by the end. The text is also broken (answer False) when an opening tag, a closing tag or a comment starts but does not finish correctly, as in <p or </p x>.
well_nested('<div><p>Hi <b>there</b></p></div>') # returns True well_nested('<b><i>oops</b></i>') # returns False well_nested('<p>Line<br>break <img src="a.png"/></p>') # returns True well_nested('<ul><li>One</ul>') # returns False
html has at most 300,000 characters, all ASCII.First solves only, ranked by stars and then time.