code-challenge regex [tag:H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ]
Parse HTML with regex!
Alternate titles:
H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ - Parse HTML with regex
Background
Don't parse HTML with regex. It always fails and sometimes summons Cthulhu.
But, because PPCG is different, we will parse HTML with regex.
And not easy, beginner HTML. HTML with comments, attributes with no quotes, HTML in script tags not commented out and much more. Can you write a regex to parse that?
The challenge
Your challenge is to make a regex that matches valid HTML tags. Don't match comments, don't match invalid HTML, don't match HTML in comments, just match valid HTML tags. Each full regex match is one HTML tag.
Your input HTML will never contain commas. You will try to get the most points possible by successfully matching the HTML tags and not the text in as many inputs as possible. Whoever gets the most points wins. Please say at least 1 regex flavor that your regex works with.
You are not allowed to use regex features to execute language code. (Sorry, Perl)
The length of your regex is irrelevant, this is not code golf.
Test cases
Here are the test cases. You can also find them at https://hastebin.com/raw/mikaxakipe.txt.
1,1,<b>HTML!</b>,<b>,</b>
2,1,<i><b>HTML</b></i>,<i>,<b>,</b>,</i>
3,1,a < b implies b > a,
4,2,<img alt=text>Img,<img alt=text>
5,2,<a href = "http://example.com">Example Domain</a>,<a href = "http://example.com">,</a>
6,2,<hr><br/>,<hr>,<br/>
7,2,<div id ="hi" class="what">What</div>,<div id ="hi" class="what">,</div>
8,3,<a>fake</>,<a>
9,3,Self-closing <img src = "self-closing.jpeg" />?,<img src = "self-closing.jpeg" />
10,3,<self-closed/>O_O<unclosed>,<self-closed/>,<unclosed>
11,3,Do<yOU>like<LoTs>of<mIXeD><cAsE>?,<yOU>,<LoTs>,<mIXeD>,<cAsE>
12,3,Wh<a b='c'd="e">at?,<a b='c'd="e">
13,3,Hi<p data-hi=3>hihihi</p>,<p data-hi=3>,</p>
14,4,<a"oops">Oops,
15,5,<!-- <b><!--hi--><i>,<i>
16,5,<0>NOT VALID</0><h0>fine</h0>,<h0>,<h0>
17,5,<a a=b<>what</a>,<a a=b<>,</a>
18,6,<!-- <b><!--hi--><i>-->,<i>
19,7,<how><deep can><your nesting nesting><level></level></go>?<how>Deep</how><can><your>nesting <go x=? j><how><deep can><your nesting nesting><level></level></go>?<how>Deep</how><can><your>nesting <go x=? j><how><deep can><your nesting nesting><level></level></go>?<how>Deep</how><can><your>nesting <go x=? j></your></can></your></deep></how></your></can></your></deep></how></your></can></your></deep></how>,<how>,<deep can>,<your nesting nesting>,<level>,</level>,</go>,<how>,</how>,<can>,<your>,<go x=? j>,<how>,<deep can>,<your nesting nesting>,<level>,</level>,</go>,<how>,</how>,<can>,<your>,<go x=? j>,<how>,<deep can>,<your nesting nesting>,<level>,</level>,</go>,<how>,</how>,<can>,<your>,<go x=? j>,</your>,</can>,</your>,</deep>,</how>,</your>,</can>,</your>,</deep>,</how>,</your>,</can>,</your>,</deep>,</how>
20,7,<plaintext><b></plaintext>,<plaintext>,</plaintext>
21,7,What<img src="imgs/>lolz.png" alt = "<heh"/>,<img src="imgs/>lolz.png" alt = "<heh"/>
22,7,<b><a href = "#" title = "4 > 3">hi</a></b>,<b>,<a href = "#" title = "4 > 3">,</a>,</b>
23,10,<StYle><b title = "not in html"></style><B>HTML!</b><style></style>,<StYle>,</style>,<B>,</b>,<style></style>
24,10,<script>//<script>< /script></script><script></script><p>,<script>,</script>,<script>,</script>,<p>
25,10,<i></i this="will be removed by a browser">,<i>,</i this="will be removed by a browser">
26,10,<div id="hi" class=class="what" data-the="heck='is'this" get-good>Attributes are weird<div>,<div id="hi" class=class="what" data-the="heck='is'this">,<div>
27,10,<!--<b>Do you like comments??</b>--><p>,<p>
28,13,<textarea><script>/* *////*///*<!--</script><b>WHAT</b></textarea><i>Hi-->,<textarea>,</textarea>,<i>
29,15,<!--<b>Do you like comments??</b><script>--><script>//<!--hello</script><b>hi</b><!--What--><script>//<!-- <script> <!-- <script> --> </script><i>hello--><script></script>,<b>,</b>,<script>,</script>,<i>,<script>,</script>
30,15,<hi>hi</hi><0>hi</0><h0>hi</h0><h&>hi</h&><&>hi</&><??>hi</??><?php>hi</?php><php?>hi</php?><->hi</-><_-_>hi</_-_><h->hi</h-><_>hi</_><h-_>hi</h-_><?>hi</?><{>hi</{><h{>hi</h{></>hi<//><h~!@#$%^&*()>hi</h~!@#$%^&*()><h>hi</h><h~>hi</h~><h!>hi</h!><@>hi</@><h@>hi</h@><h!@#$%^&*()>hi</h!@#$%^&*()><@f>hi</@f><%>hi</%><;>hi</;><h>>hi</h>><h&>hi</h&><h~>hi</h~>,<hi>,</hi>,<h0>,</h0>,<H&>,</H&>,<PHP?>,</PHP?>,<h->,</h->,<H-_>,</H-_>,<H{>,</H{>,<H~!@#$%^&*()>,</H~!@#$%^&*()>,<H>,</H>,<H~>,</H~>,<H!>,</H!>,<h@>,</h@>,<h!@#$%^&*()>,</h!@#$%^&*()>,<H>,</H>,<H&>,</H&>,<h~>,</h~>
31,30,<hi>hi</hi><0 WHAT_is=HtMl>hi&<i attrubute="oops'></0><h0 attRiBu350Te="<b>oops</b><style>/*">hi</h0>*/<h&>hi</h&><&>hi</&><??>hi</??><?php>hi</?php><php?>hi</php?><->hi</-><_-_>hi</_-_><h->hi</h-><_>hi</_><h-_>hi</h-_><?>hi</?><{>hi</{><h{>hi</h{></>hi&<//><script> &/*<h~!@#$%^&*()>*/</ script></StyLe>/*</ScrIPT>/*<b>oops</b>hi</h~!@#$%^&*()><h>hi</h><h~>hi</h~><h!>hi</h!><@>hi</@><h@>hi</h@><h!@#$%^&*()>hi</h!@#$%^&*()><@f>hi</@f><%>hi</%><;>hi</;><h>>hi</h>><h&>hi&</h&><h~>hi/*/</h~><b>oops</b>hi</h~!@#$%^&*()><h>hi</h><h~>hi</h~><h!>hi</h!><@>hi</@><h@>hi</h@><h!@#$%^&*()>hi</h!@#$%^&*()><@f>hi</@f><%>hi</%><;>hi</;><h>>hi</h>><h&>hi&</h&><h~>hi/<script></StyLe></ScrIPT><textarea><b>HE COMES</b></textarea><h!>hi</h!><@>hi</@><h@>hi</h@><h!@#$%^&*()>hi</h!@#$%^&*()><@f>hi</@f><%>hi</%><;>hi</;><h>>hi</h>><h&>hi&</h&><h~>hi</h~>,<hi>,</hi>,<i attrubute="oops'></0><h0 attRiBu350Te="<b>,<style>,</style>,<textarea>,</textarea>,<h!>,</h!>,<h@>,</h@>,<h!@#$%^&*()>,</h!@#$%^&*()>,<h&>,</h&>,<h~></h~>
Each line is a separate test case. They are in this format:
1,1,<b>HTML!</b>,<b>,</b>
| | | | |
| | | +---+- The correct output: all HTML tags in the string separated by commas
| | +- The HTML for you to parse
| +- The number of points you get if you parse this HTML correctly
+- The test case number
Example
Let's say we have the regex /<.*?>/g
(all flavors). For test case #1, it matches 2 times: <b>
, and </b>
. The correct output in the test case says that it should match <b>
and </b>
, so it is correct. Our regex gets 1 point.
Then for test case #2. Our regex matches <i>
, <b>
, </b>
, and </i>
, which is consistent with the test case so we get 1 point.
Now for test case #3. Our regex matches < b implies b >
, when it should have not matched anything. We get 0 points for that.
Continuing for each test case gets us a score of 50 (out of 207, or 24.15%). Not great. Can you do better?
Try It Online
If your regex will work with the ECMAScipt / JS flavor than you can try it here and get automatic scoring!
Tie breaker
Here are the scoring systems. Whoever has the best score on the first wins. In the event of a tie, whoever out of the ties scores the best wins, etc.
- Most points
- Shortest length
- First posted
Answer format
[insert score here] / 207 points
[insert regex here]
Explanation (optional but encouraged)
Proof of score (matched output vs. test cases, link to TIO to try it,
etc.)
Meta