@daftcoder のソリューションが機能する場合、それは素晴らしいことですが、コードにエンティティ (< など) がある場合は失敗します。他に失敗した例は見つかりませんでした。
それが重要な場合は、PHP で DOM 操作を使用できます。これはかなり複雑ですが、単純な正規表現よりも多くの場合に機能するはずです。
walk 関数と doReplace 関数は、別の質問への回答から JS から PHP に変換されます。( HTML テキスト内の個々の単語を SPAN タグで囲みますか? )
<?php
echo wrap_words('span', 'Lorem ipsum dolor sit amet, <a href="#">consectetuer adipiscing</a> elit, <strong>tincidunt</strong> ut volutpat.');
function wrap_words($tag, $text) {
    $document = new DOMDocument();
    $fragment = $document->createDocumentFragment();
    $fragment->appendXml($text);
    walk($tag, $fragment);
    $html = $document->saveHtml($fragment);
    // using saveHTML with a documentFragment can leave an invalid "<>"
    // at the beginning of the string - remove it
    return preg_replace('/^<>/', '', $html);
}
function walk($tag, $root)
{
    if ($root->nodeType == XML_TEXT_NODE)
    {
        doReplace($tag, $root);
        return;
    }
    $children = $root->childNodes;
    for ($i = $children->length - 1; $i >= 0; $i--)
    {
        walk($tag, $children->item($i));
    }
}
function doReplace($tag, $text)
{
    $fragment = $text->ownerDocument->createDocumentFragment();
    $fragment->appendXML(preg_replace('/\S+/', "<{$tag}>\$0</{$tag}>", $text->nodeValue));
    $parent = $text->parentNode;
    $children = $fragment->childNodes;
    for ($i = $children->length - 1; $i >= 0; $i--)
    {
        $parent->insertBefore($children->item($i), $text->nextSibling);
    }
    $parent->removeChild($text);
}