PHP:使用<a> tags, ellipses, and link icons</a>查找,替换,缩短和美化用户链接

时间:2010-11-03 21:35:02

标签: php url prettify

当用户输入网址时,例如http://www.google.com,我希望能够使用PHP解析该文本查找任何链接并将其替换为 {{ 1}}包含原始网址为<a>的标记。

换句话说,HREF将成为

http://www.google.com

我希望能够为这些表单的所有网址执行此操作(<a href="http://www.google.com">http://www.google.com</a>可与任何TLD互换):

.com

最有效的方法是什么?我可以尝试写一些非常花哨的正则表达式,但我怀疑这是我可以使用的最佳方法。

对于奖励积分,我还希望将http://www.google.com www.google.com google.com docs.google.com 添加到缺少它的任何网址,并将显示文本本身剥离为http://形式的某些内容,然后显示外部链接图标。

6 个答案:

答案 0 :(得分:1)

试图找到格式为domain.com的链接将是一个痛苦的屁股。它需要跟踪所有顶级域名并在搜索中使用它们。如果你没有输入我输入的最后一个句子的结尾,那么这句话的开头就是http://search.if的链接。即使你这样做.in是有效的TLD和常用词。

我建议告诉您的用户他们必须开始与www.http://建立链接,然后编写一个简单的正则表达式来捕获它们并添加链接。

答案 1 :(得分:1)

  

www.google.com

这不是网址,而是主机名。在任意文本中开始标记裸主机名通常不是一个好主意,因为在一般情况下,点分隔词的任何单词或序列都是完全有效的主机名。这意味着您可能会遇到可疑的黑客,例如寻找领先的www.(并且您会收到诸如“为什么我可以链接到www.stackoverflow.com而不是stackoverflow.com?”或“尾随TLD”的问题(随着更多新TLD的推出,越来越不切实际;“为什么我喜欢ncm.com但不喜欢ncm.museum?”),而且你经常会标记那些不应该是链接的东西。< / p>

  

我可以尝试写一些非常花哨的正则表达式

好吧,我看不到你如何做没有正则表达式。

诀窍是应对标记。如果输入中包含<&"个字符,则不得让它们进入HTML输出。如果您的输入是纯文本,则可以在对nico的答案中的模式应用简单替换之前调用htmlspecialchars()来执行此操作。

(如果输入已包含标记,则表示您遇到问题,并且您可能需要一个HTML解析器来确定哪些位是标记,以避免在其中添加更多标记。同样,如果您在此之后进行更多处理插入更多标签,这些步骤可能会有同样的难度。在'bbcode'类语言中,这通常会导致错误和安全问题。)

另一个问题是落后标点符号。人们常常在链接后设置句号,逗号,右括号,感叹号等,这些链接不应该是链接的一部分,但实际上是有效字符。剥离它们并不将它们放在链接中是有用的。但是你打破了以)结尾的Wiki链接,所以如果链接中有),或者类似的话,你可能不想将(视为尾随字符。这种事情不能在简单的正则表达式替换中完成,但您可以在替换回调函数中完成。

答案 2 :(得分:1)

HTML Purifierbuilt-in linkify function可以帮助您解决所有问题。

如果您正在处理您还必须显示的任何类型的用户输入,那么其他功能也非常有用。

答案 3 :(得分:0)

不那么花哨的正则表达式

/\b(https?:\/\/[^\s+\"\<\>]+)/ig
/\b(www.[^\s+\"\<\>]+)/ig

请注意,最后两个是不可能正确完成的,因为你无法将google.com与这样的东西区分开来。我完成了一个句子并且在完全停止后没有放置空格。

至于缩短网址,将您的网址设为$url

if (strlen($url) > 20) // Or whatever length you like
   {
   $shortURL = substr($url, 0, 20)."&hellip;";
   }
else
   {
   $shortURL = $url;
   }

echo '<a href="'.$url.'" >'.$shortURL.'</a>';

答案 4 :(得分:0)

我按照我想要的方式完成了这项工作:

<?php

$input = <<<EOF
http://www.example.com/
http://example.com
www.example.com
http://iamanextremely.com/long/link/so/I/will/be/trimmed/down/a/bit/so/i/dont/mess
/up/text/wrapping.html
EOF;

  function trimlong($match)
  {
    $url = $match[0];
    $display = $url;
    if ( strlen($display) > 30 ) {
      $display = substr($display,0,30)."...";
    }
    return '<a href="'.$url.'">'.$display.' <img src="http://static.goalscdn.com/img/external-link.gif" height="10" width="11" /></a>';
  }

$output = preg_replace_callback('#(http://|www\\.)[^\\s<]+[^\\s<,.]#i',
                                 array($this,'trimlong'),$input);

echo $output;

答案 5 :(得分:0)

来自http://www.exorithm.com/algorithm/view/markup_urls

function markup_urls ($text)
{
  // split the text into words
  $words = preg_split('/([\s\n\r]+)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
  $text = "";

  // iterate through the words
  foreach($words as $word) {

    // chopword = the portion of the word that will be replaced
    $chopword = $word;
    $chopword = preg_replace('/^[^A-Za-z0-9]*/', '', $chopword);

    if ($chopword <> '') {
      // linkword = the text that will replace chopword in the word
      $linkword='';

      // does it start with http://abc. ?
      if (preg_match('/^(http:\/\/)[a-zA-Z0-9_]{2,}.*/', $chopword)) {

        $chopword = preg_replace('/[^A-Za-z0-9\/]*$/', '', $chopword);
        $linkword = '<a href="'.$chopword.'" target="blank">'.$chopword.'</a>';

      // does it equal abc.def.ghi ?
      } else if (preg_match('/^[a-zA-Z]{2,}\.([a-zA-Z0-9_]+\.)+[a-zA-Z]{2,}(\/.*)?/', $chopword)) {

        $chopword = preg_replace('/[^A-Za-z0-9\/]*$/', '', $chopword);
        $linkword = '<a href="http://'.$chopword.'" target="blank">'.$chopword.'</a>';

      // does it start with abc@def.ghi ?
      } else if (preg_match('/^[a-zA-Z0-9_\.]+\@([a-zA-Z0-9_]{2,}\.)+[a-zA-Z]{2,}.*/', $chopword)) {

        $chopword = preg_replace('/[^A-Za-z0-9]*$/', '', $chopword);
        $linkword = '<a href="mailto:'.$chopword.'">'.$chopword.'</a>';

      }

      // replace chopword with linkword in word (if linkword was set)
      if ($linkword <> '') {
        $word = str_replace($chopword, $linkword, $word);
      }
    }

    // append the word
    $text = $text.$word;
  }

  return $text;
}