你的问题实际上可以分解为两个较小的问题。您已经解决了其中一个问题,即使用正则表达式解析URL。第二部分是从HTML中提取文本,这根本不容易用正则表达式来解决。您遇到的困惑是,试图用正则表达式同时完成这两项任务(解析HTML和解析URL)。请参阅
parsing HTML with regex SO Answer
了解更多关于为什么这是个坏主意的细节。
所以,让我们使用一个HTML解析器(比如
DOMDocument
)从HTML中提取文本节点,并解析这些文本节点内的URL。
这里有一个例子
<?php
$html = <<<'HTML'
<p>This is a URL http://abcd/ims in text</p>
HTML;
$dom = new DOMDocument;
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
// Let's walk the entire DOM tree looking for text nodes
function walk(DOMNode $node, $skipParent = false) {
if (!$skipParent) {
yield $node;
}
if ($node->hasChildNodes()) {
foreach ($node->childNodes as $n) {
yield from walk($n);
}
}
}
foreach (walk($dom->firstChild) as $node) {
if ($node instanceof DOMText) {
// lets find any links and change them to HTML
if (preg_match('/(http[s]{0,1}\:\/\/\S{4,})\s{0,}/ims', $node->nodeValue, $match)) {
$node->nodeValue = preg_replace('/(http[s]{0,1}\:\/\/\S{4,})\s{0,}/ims', "\xff ",
$node->nodeValue);
$nodeSplit = explode("\xff", $node->nodeValue, 2);
$node->nodeValue = $nodeSplit[1];
$newNode = $dom->createTextNode($nodeSplit[0]);
$href = $dom->createElement('a', $match[1]);
$href->setAttribute('href', $match[1]);
$node->parentNode->insertBefore($newNode, $node);
$node->parentNode->insertBefore($href, $node);
}
}
}
echo $dom->saveHTML();
这将为您提供所需的HTML作为输出:
<p>This is a URL <a href="http://abcd/ims">http://abcd/ims</a> in text</p>