php 点击链接时url不变,关于url:可点击链接的最佳PHP脚本

博客讨论了在PHP中使用正则表达式和DOM解析器将纯文本URL转换为可点击链接的问题。作者指出,许多现有的脚本存在错误,可能将已有的可点击链接再次转换,导致格式混乱。文章提供了两段代码,一个是使用正则表达式的简单实现,另一个是使用DOMDocument和XPath的更复杂解决方案,旨在避免重复转换和在文本中遗漏链接。作者寻求帮助改进代码,确保只转换未被标记的文本链接。
摘要由CSDN通过智能技术生成

我发现许多PHP脚本可将文本中的URL转换为可单击的链接。 但是它们大多数无法正常工作,有些会产生很大的错误。 其中一些转换链接已经可以单击。 其他人则无法使用,而第三者则通过文本链接制作零件。

我需要一个脚本,该脚本将仅检测链接,而不检测文本,并且不会转换已经可单击的链接,因为它的运行非常难看。

我发现这段代码似乎是我测试过的最好的代码。 但是它有一些错误。

此代码转换可点击的链接。 像这样:

原版的:

http://www.netload.in/dateiySgPP2b14W/1409...7ExpFut.pdf.htm

已转换:

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

\(\)"\'<>\,\!]+)/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, ''. $urltext .'', $text);

}

}

return $text;

}

如果您告诉我们出了什么问题以及所需的输出应该是什么,可能会有所帮助。 您发布的转换后的链接看起来并不像您想要的那样,但是同样,您的问题并没有提供有关应该发生什么的太多信息。

@Wouter他的问题为应该发生的事情提供了大量信息。 他不希望正则表达式捕获标记之间的链接。 我不明白他的意图是:他是否要我们帮助他修复此代码,还是他要我们为他提供另一个解析器?

您会看到转换后的链接不正确。 我需要从脚本中检测仅文本格式的链接,而不检测文本的一部分,并且不转换已经可单击的链接,因为它的操作非常难看

@Palladium我显示此代码是因为有人可以尝试修复他。 但是,如果有人知道已经很不错了,那么可以使用工作代码来替换它。

我只是把这些放在一起。

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

\(\)"\'<>\,\!]+)/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 = <<

http://google.com

Stuff http://google.com

asdf http://google.com ffaa

HTML;

// Process the HTML and echo it out.

echo replaceUrlsWithLinks($html);

?>

输出为:

http://google.com

Stuff http://google.com

asdf http://google.com ffaa

您不应该使用正则表达式来操纵HTML。

希望这可以帮助。

凯尔

-编辑-

先前的代码效率更高,但是如果您计划在同一父节点中具有两个URL,则该代码将因为DOM树已更改而中断。 要解决此问题,您可以使用以下更密集的代码:

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

\(\)"\'<>\,\!]+)/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 = <<

http://google.com

Stuff http://google.com

asdf http://google.com ffaa  http://google.com

HTML;

echo replaceUrlsWithLinks($html);

?>

谢谢! 那很棒;)

当您尝试使用正则表达式解析HTML时,您会遇到通常发生的问题。 您需要适当的HTML解析器。 看看这个线程。

此函数在锚标记中包装http://www.domain.com之类的文本。 我在这里看到的是您正在尝试将锚标记转换为锚标记,这当然是行不通的。 因此:不要在文本中编写锚点,而是让脚本为您创建锚点。

该脚本是自动化的,有些团队拥有标签将非常有用,但不幸的是。 另一种方法是删除锚标记。

好。 我不知道。 当您要删除标签时,请注意click here之类的构造。 您将必须同时获取url和链接文本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值