我发现很多PHP脚本可以将文本中的网址转换为可点击的链接。但是他们中的大多数都不起作用,有些人犯了很大的错误。其中一些转换已经可点击的链接。其他人不工作,第三个从文本链接制作部分。 我需要一个只检测链接的脚本,而不是文本,并且不会转换已经可点击的链接,因为它会非常难看。
我发现这个代码似乎是我测试过的最好的代码。但它有一些错误。 此代码转换可点击链接。像这样:
原件:
<a href="http://www.netload.in/dateiySgPP2b14W/1409423417ExpFut.pdf.htm" target="_blank">http://www.netload.in/dateiySgPP2b14W/1409...7ExpFut.pdf.htm</a>
转换:
http://www.netload.in/dateiySgPP2b14W/1409423417ExpFut.pdf.htm" target="_blank">http://www.netload.in/dateiySgPP2b14W/1409...7ExpFut.pdf.htm
以下是代码:
function parse_urls($text, $maxurl_len = 35, $target = '_self') // Make URLs Clickable
{
if (preg_match_all('/((ht|f)tps?:\/\/([\w\.]+\.)?[\w-]+(\.[a-zA-Z]{2,4})?[^\s\r\n\(\)"\'<>\,\!]+)/si', $text, $urls))
{
$offset1 = ceil(0.65 * $maxurl_len) - 2;
$offset2 = ceil(0.30 * $maxurl_len) - 1;
foreach (array_unique($urls[1]) AS $url)
{
if ($maxurl_len AND strlen($url) > $maxurl_len)
{
$urltext = substr($url, 0, $offset1) . '...' . substr($url, -$offset2);
}
else
{
$urltext = $url;
}
$text = str_replace($url, '<a href="'. $url .'" target="'. $target .'" title="'. $url .'">'. $urltext .'</a>', $text);
}
}
return $text;
}
答案 0 :(得分:2)
我把它扔到了一起。
<?php
function replaceUrlsWithLinks($text){
$dom = new DOMDocument;
$dom->loadXML($text);
$xpath = new DOMXpath($dom);
$query = $xpath->query('//text()[not(ancestor-or-self::a)]');
foreach($query as $item){
$content = $item->textContent;
if(preg_match_all('/((ht|f)tps?:\/\/([\w\.]+\.)?[\w-]+(\.[a-zA-Z]{2,4})?[^\s\r\n\(\)"\'<>\,\!]+)/si',$content,$matches,PREG_SET_ORDER | PREG_OFFSET_CAPTURE)){
foreach($matches as $match){
$newA = $dom->createElement('a',$match[0][0]);
$newA->setAttribute('href',$match[0][0]);
$newA->setAttribute('target','_blank');
$a = $item->splitText($match[0][1]);
$b = $a->splitText(strlen($match[0][0]));
$a->parentNode->replaceChild($newA,$a);
}
}
}
return $dom->saveHtml();
}
// The HTML to process ...
$html = <<<HTML
<block>
<a href="http://google.com">http://google.com</a>
<b>Stuff http://google.com</b>
asdf http://google.com ffaa
</block>
HTML;
// Process the HTML and echo it out.
echo replaceUrlsWithLinks($html);
?>
输出结果为:
<block>
<a href="http://google.com">http://google.com</a>
<b>Stuff <a href="http://google.com" target="_blank">http://google.com</a></b>
asdf <a href="http://google.com" target="_blank">http://google.com</a> ffaa
</block>
您不应该使用正则表达式来操纵HTML。
希望这有帮助。
凯尔
- 编辑 -
以前的代码效率更高,但如果您计划在同一父节点中有两个URL,则代码将因为DOM树已更改而中断。要解决此问题,您可以使用此更密集的代码:
<?php
function replaceUrlsWithLinks($text){
$dom = new DOMDocument;
$dom->loadXML($text);
$xpath = new DOMXpath($dom);
while(true){
$shouldBreak = false;
$query = $xpath->query('//text()[not(ancestor-or-self::a)]');
foreach($query as $item){
$shouldBreak = false;
$content = $item->textContent;
if(preg_match_all('/((ht|f)tps?:\/\/([\w\.]+\.)?[\w-]+(\.[a-zA-Z]{2,4})?[^\s\r\n\(\)"\'<>\,\!]+)/si',$content,$matches,PREG_SET_ORDER | PREG_OFFSET_CAPTURE)){
foreach($matches as $match){
$newA = $dom->createElement('a',$match[0][0]);
$newA->setAttribute('href',$match[0][0]);
$newA->setAttribute('target','_blank');
$a = $item->splitText($match[0][1]);
$b = $a->splitText(strlen($match[0][0]));
$a->parentNode->replaceChild($newA,$a);
$shouldBreak = true;
break;
}
}
if($shouldBreak == true)break;
}
if($shouldBreak == true){
continue;
}
else {
break;
}
}
return $dom->saveHtml();
}
$html = <<<HTML
<block>
<a href="http://google.com">http://google.com</a>
<b>Stuff http://google.com</b>
asdf http://google.com ffaa http://google.com
</block>
HTML;
echo replaceUrlsWithLinks($html);
?>
答案 1 :(得分:0)
此函数将http://www.domain.com
之类的文本包含在锚标记中。我在这里看到的是你正在尝试将锚标签转换为锚标签,这当然是行不通的。所以:不要在你的文本中写下锚点,让脚本为你创建它们。
答案 2 :(得分:0)
当您尝试使用正则表达式解析HTML时,您正在遇到usual problems。您需要一个合适的HTML解析器。看看this thread。