0
4

6 回答 6

1
于 2010-11-03T21:46:05.387 回答
1

www.google.com

这不是 URL,而是主机名。在任意文本中开始标记裸主机名通常不是一个好主意,因为在一般情况下,任何单词或点分隔的单词序列都是完全有效的主机名。这意味着你会遇到可怕的黑客攻击,比如寻找领先的www.(你会得到诸如“为什么我可以链接www.stackoverflow.com但不能链接stackoverflow.com?”)或尾随 TLD(随着更多新 TLD 的引入,这变得越来越不切实际;“为什么可以我喜欢 ncm.com 但不喜欢ncm.museum?”),而且您经常会标记不应该是链接的内容。

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

好吧,如果没有正则表达式,我看不出你会怎么做。

诀窍是处理标记。如果您可以在输入中包含<,&"字符,则不能让它们进入 HTML 输出。如果您的输入是纯文本,您可以通过htmlspecialchars()在对像 nico 的答案那样的模式应用简单替换之前调用来做到这一点。

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

另一个问题是尾随标点符号。人们通常在链接后加上句号、逗号、右括号、感叹号等,这些不应该是链接的一部分,但实际上是有效字符。将它们剥离而不是将它们放入链接中很有用。但是随后您破坏了以 结尾的 Wiki 链接,因此如果链接中有 a 或类似的东西,)您可能不想将)其视为尾随字符。(这种事情不能在简单的正则表达式替换中完成,但您可以在替换回调函数中完成。

于 2010-11-03T21:53:11.140 回答
1

HTML Purifier有一个内置的链接功能,可以为您省去所有的麻烦。

如果您要处理还必须显示的任何类型的用户输入,那么它的其他功能也太有用了,不容忽视。

于 2010-11-04T00:26:24.840 回答
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>';
于 2010-11-03T21:44:57.727 回答
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;
于 2010-11-03T21:47:50.983 回答
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;
} 
于 2010-11-04T00:09:25.977 回答