Это будет находить верхнюю часть каждого тега, если вы не вкладываете теги p в теги p или ul в ul. Но вы можете вложить p в ul, например. Для сложных HTML вы лучше с DOM .
Пример данных:
$html = <<< EOF
<p>
hey
</p>
<ul>
<li>
test
</li>
<li>
<p>
df4r4 4f4
</p>
</li>
</ul>
<p>
hoo
</p>
EOF;
Regex:
$regex = '#<(?P<tags>(?i)p|ul|ol)>(?P<values>.*?)</\1>#si';
preg_match_all($regex, $html, $output);
Сортировать по тегам:
for ($i = 0, $t = count($output['tags']); $i < $t; $i++) {
$out[$output['tags'][$i]][] = $output['values'][$i];
}
Теги и значения отдельно, удалите дубликаты с целочисленным ключом и совпадение всей строки:
$output = array_intersect_key($output, array('tags' => 0, 'values' => 0));