<?php

function retornarInfo($texto, $classe) {
	$expressao = '~id="([\w]+)" class="'. $classe .'"~i';
	$casamento = preg_match($expressao, $texto, $resultado);
	return (($casamento == 1 ? $resultado[1] : ""));	  
}

$documento = '<ul id="titulo1" class="titulo">
   <li>
      <p>TÍTULO I</p>
   </li>
</ul>
<ul id="artigo1" class="artigo">
   <li>
      <p>Art. 1º...</p>
   </li>
</ul>
<ul id="artigo2" class="artigo">
   <li>
      <p>Art. 2º ....</p>
   </li>
</ul>
<ul id="artigo3" class="artigo">
   <li>
      <p>Art. 3º ....:</p>
   </li>
</ul>
<ul id="artigo4" class="artigo">
   <li>
      <p>Art. 4º ....:</p>
   </li>
</ul>
<ul id="titulo2" class="titulo">
   <li>
      <p>TÍTULO II</p>
   </li>
</ul>
<ul id="capitulo1" class="capitulo">
   <li>
      <p>CAPÍTULO I</p>
   </li>
</ul>
<ul id="artigo5" class="artigo">
   <li>
      <p>Art. 5º ....:</p>
   </li>
</ul>
<ul id="capitulo2" class="capitulo">
   <li>
      <p>CAPÍTULO II</p>
   </li>
</ul>
<ul id="artigo6" class="artigo">
   <li>
      <p>Art. 6º ...</p>
   </li>
</ul>
<ul id="artigo7" class="artigo">
   <li>
      <p>Art. 7º ...</p>
   </li>

</ul>
<ul id="artigo8" class="artigo">
   <li>
      <p>Art. 8º....:</p>
   </li>
</ul>
<ul id="artigo9" class="artigo">
   <li>
      <p>Art. 9º É as.</p>
   </li>
</ul>
<ul id="artigo10" class="artigo">
   <li>
      <p>Art. 10. ....</p>
   </li>
</ul>
<ul id="artigo11" class="artigo">
   <li>
      <p>Art. 11. ....</p>
   </li>
</ul>
<ul id="capitulo3" class="capitulo">
   <li>
      <p>CAPÍTULO III</p>
   </li>
</ul>
<ul id="artigo12" class="artigo">
   <li>
      <p>Art. 12. São brasileiros:</p>
   </li>
</ul>';

function criarHierarquia($linhas){
	$informacoes = [];
	$indiceTitulo = $indiceCapitulo = "";
	
	foreach ($linhas as $linha){
		$titulo   = retornarInfo($linha, "titulo");
		$capitulo = retornarInfo($linha, "capitulo");
		$artigo   = retornarInfo($linha, "artigo");
		
		if (!empty($titulo))
			$indiceTitulo = $titulo;
		if (!empty($capitulo)){
			$indiceCapitulo = $capitulo;
		} elseif (!empty($artigo)){
			if (!empty($indiceCapitulo))
				$informacoes["titulo"][$indiceTitulo]["artigo"][$indiceCapitulo][] = $artigo;
			else
				$informacoes["titulo"][$indiceTitulo]["artigo"][] = $artigo;
		}
	}
	return $informacoes;
}
 
$linhas = explode("<ul", $documento);
$informacoes = criarHierarquia($linhas);

foreach ($informacoes as $info){
	foreach ($info as $titulo => $artigos){
		echo "{$titulo}" . PHP_EOL;
		foreach ($artigos as $artigo){
			foreach ($artigo as $capitulo => $subArtigo){
				if (is_array($subArtigo)){
					foreach($subArtigo as $capArtigo){
						echo "{$titulo}{$capitulo}{$capArtigo}" . PHP_EOL;
					}					
				} else {
					echo "{$titulo}{$subArtigo}" . PHP_EOL;
				}
			}
		}
	}
}
?>