Lessons · Regex · why not to parse HTML with one
HTML nests and a pattern cannot count
Attributes in any order, unclosed tags, comments, script bodies containing '<', and tags inside tags: a pattern handles the page you tested and not the page you get.
Hone is a place to practise programming. This is one of its lessons, written out in full and free to read without an account.
What it is for
It is the best-known example of the general rule, and the general rule is what matters: a format that nests needs something that can keep track of depth.
How to think about it
Output you generate yourself, one known marker: a pattern is fine and everybody does it. Somebody else's HTML: html.parser is in the standard library.
Worked example
re.findall(r'<b>(.*?)</b>', '<b>one</b> <i><b>two</b></i>')It found both, and told you nothing about which is nested inside what.
re.findall(r'<b>(.*?)</b>', '<b>a <b>b</b></b>')And here it is simply wrong: the first match stops at the inner closing tag.
Your turn
Take the text inside each bold tag, in output you generate yourself.
re.findall(r'<b>(.?)</b>', '<b>one</b> <i><b>two</b></i>')
Test a pattern against real text
The trap
The lazy quantifier that makes the simple case work is exactly what makes the nested case wrong.