Now, here's no Regex expert but should he be in your shoes; He'd do it like so:
    <?php
        // SIMULATED SAMPLE HTML CONENT - WITH ATTRIBUTES:
        $contents = '<section id="id-1">And even when darkness covers your path and no one is there to lend a hand;
            <h3 class="class-1">Always remember that <em>There is always light at the end of the Tunnel <span class="class-2">if you can but hang on to your Faith!</span></em></h3>
            <div>Now; let no one deceive you: <h2 class="class-2">You will be tried in ever ways - sometimes beyond your limits...</h2></div>
            <article>But hang on because You are the Voice... You are the Light and you shall rule your Destiny because it is all about<h6 class="class4">YOU - THE REAL YOU!!!</h6></article>
            </section>';
        // SPLIT THE CONTENT AT THE END OF EACH <h[1-6]> TAGS   
        $parts      = preg_split("%<\/h[1-6]>%si", $contents);
        $matches    = array();
        // LOOP THROUGH $parts AND BUNDLE APPROPRIATE ELEMENTS TO THE $matches ARRAY.       
        foreach($parts as $part){
            if(preg_match("%(.*|.?)(<h)([1-6])%si", $part)){
                $matches[] = preg_replace("%(.*|.?)(<)(h[1-6])(.*)%si", "$2$3$4$2/$3>", $part);
            }
        }
        var_dump($matches);
        //DUMPS::::
        array (size=3)
          0 => string '<h3 class="class-1">Always remember that <em>There is always light at the end of the Tunnel <span class="class-2">if you can but hang on to your Faith!</span></em></h3>' (length=168)
          1 => string '<h2 class="class-2">You will be tried in ever ways - sometimes beyond your limits...</h2>' (length=89)
          2 => string '<h6 class="class4">YOU - THE REAL YOU!!!</h6>' (length=45)
As a Function, this is what it boils down to:
 <?php
        function pseudoMatchHTags($htmlContentWithHTags){
            $parts      = preg_split("%<\/h[1-6]>%si", $htmlContentWithHTags);
            $matches    = array();
            foreach($parts as $part){
                if(preg_match("%(.*|.?)(<h)([1-6])%si", $part)){
                    $matches[] = preg_replace("%(.*|.?)(<)(h[1-6])(.*)%si", "$2$3$4$2/$3>", $part);
                }
            }
            return $matches;
        }
        var_dump(pseudoMatchHTags($contents));
You can test it here: https://eval.in/571312   ... perhaps it helps a bit... i hope... ;-)