问题:将文本 URL 转换为超链接可能是一项有用的任务,但当 HTML 标签中的图像或其他元素也包含 URL 时,这就变得具有挑战性。在特定实例中,用户寻求一种用锚标记替换文本 URL,同时避免替换图像源属性中嵌入的 URL 的方法。
解决方案:
关键解决此问题的方法是使用 XPath 表达式仅选择那些包含 URL 但不是锚元素后代的文本节点。
这是 XPath 表达式的改进版本:
$xPath = new DOMXPath($dom); $texts = $xPath->query( '/html/body//text()[ not(ancestor::a) and ( contains(.,"http://") or contains(.,"https://") or contains(.,"ftp://") )]' );
此表达式有效地排除锚标记中包含的文本节点,确保仅以纯文本 URL 为目标进行转换。
替换文本 URL 而不影响图像 URL:
为了避免替换嵌入在图像源属性中的 URL,采用了一种非标准但有效的方法。不是将文本节点分开,而是使用文档片段将整个文本节点替换为修改后的版本。
以下是执行此任务的代码:
foreach ($texts as $text) { $fragment = $dom->createDocumentFragment(); $fragment->appendXML( preg_replace( "~((?:http|https|ftp)://(?:\S*?\.\S*?))(?=\s|\;|\)|\]|\[|\{|\}|,|\"|'|:|\<|$|\.\s)~i", '<a href=""></a>', $text->data ) ); $text->parentNode->replaceChild($fragment, $text); }
在此代码中, preg_replace 函数用于搜索文本节点中的 URL,并将其替换为相应的锚标记版本。
示例:
考虑以下 HTML:
<code class="html"><html> <body> <p> This is a text with a <a href="http://example.com/1">link</a> and another <a href="http://example.com/2">http://example.com/2</a> and also another http://example.com with the latter being the only one that should be replaced. There is also images in this text, like <img src="http://example.com/foo"/> but these should not be replaced either. In fact, only URLs in text that is no a descendant of an anchor element should be converted to a link. </p> </body> </html></code>
应用上述解决方案会将文本 URL 转换为锚标记,同时保持图像 URL 不变,产生以下输出:
<code class="html"><html><body> <p> This is a text with a <a href="http://example.com/1">link</a> and another <a href="http://example.com/2">http://example.com/2</a> and also another <a href="http://example.com">http://example.com</a> with the latter being the only one that should be replaced. There is also images in this text, like <img src="http://example.com/foo"/> but these should not be replaced either. In fact, only URLs in text that is no a descendant of an anchor element should be converted to a link. </p> </body></html></code>
以上是如何用超链接替换文本 URL,同时排除 HTML 标记中的 URL?的详细内容。更多信息请关注PHP中文网其他相关文章!