$re = '/(?=<ul\s+id=""matchMe""\s+type=""square""\s*>) # match start with <ul id="matchMe"...
(?> # atomic group / don\'t backtrack (faster)
<!-- .*? --> | # match xml / html comment
<[^>]*/\s*> | # self closing tag
(?<opentag><(?!\s*/)[^>]*[^/]>) | # push opening xml tag
(?<-opentag><\s*/[^>]*[^/]>) | # pop closing xml tag
[^<>]* # something between tags
)* # match as many xml tags as possible
(?(opentag)(?!)) # ensure no \'opentag\' groups are on stack/xs';
$str = '<html>
<body>
<div>
<br />
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<p>Lorem ipsum< /p>
<hr class="important" / >
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
</div>
</body>
</html>';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for PHP, please visit: http://php.net/manual/en/ref.pcre.php