Editor

Properly Nested HTML Tags

#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:

  • An opening tag is < 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>.
  • Inside an opening tag, a > that sits within quotes (single or double) does not end the tag: <a title="x > y"> is one tag.
  • An opening tag whose last character before the > is / closes itself, like <span/> or <br />.
  • A closing tag is </, a name and >, with nothing else, like </p>.
  • These void tags never get a closing tag: 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.
  • A < 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>.

Examples

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

Constraints

  • html has at most 300,000 characters, all ASCII.
  • Tags may nest up to 50,000 deep.

Fastest solvers

Leaderboard

First solves only, ranked by stars and then time.