2

我一直在研究这个,只找到了 2 个相关的答案,但仍然没有奏效。

反正。我正在尝试在文本中查找链接并自动链接它们,如果它们已经在 html 标记中,则不自动链接它们。(< a > < img >) 并且它必须支持所有链接,例如 http、https 和 www

我对正则表达式感到恐惧,但我试图把一些东西放在一起。

function b($text)
{
   // a more readably-formatted version of the pattern is on http://daringfireball.net/2010/07/improved_regex_for_matching_urls
   $pattern  = '(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))';

   $callback = create_function('$matches', '
       $url       = array_shift($matches);
       $url_parts = parse_url($url);

       $text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH);
       $text = preg_replace("/^www./", "", $text);

       $last = -(strlen(strrchr($text, "/"))) + 1;
       if ($last < 0) {
           $text = substr($text, 0, $last) . "&hellip;";
       }

       return "<a rel="nofollow" href=".$url.">".$text."</a>";
   ');

   return preg_replace_callback($pattern, $callback, $text);
}

function autolink($txt)
{
    return preg_replace_callback('#(?<!href\=[\'"])(https?|ftp|file)://[-A-Za-z0-9+&@\#/%()?=~_|$!:,.;]*[-A-Za-z0-9+&@\#/%()=~_|$]#', 'b', $txt);
}

但没有运气,我现在不知道该怎么做。

4

1 回答 1

5

您需要某种 HTML 解析器才能使其完美运行。请记住,还有其他标签/语法可以包含 URL,例如<script><style>、评论等。

如果解决问题中的问题的简单正则表达式解决方案足以满足您的情况,您可以使用以下内容:

function linkify($input){
    $re = <<<'REGEX'
!
    (
      <\w++
      (?:
        \s++
      | [^"'<>]++
      | "[^"]*+"
      | '[^']*+'
      )*+
      >
    )
    |
    (\b https?://[^\s"'<>]++ )
    |
    (\b www\d*+\.\w++[^\s"'<>]++ )
!xi
REGEX;

    return preg_replace_callback($re, function($m){
        if($m[1]) return $m[1];
        $url = htmlspecialchars($m[2] ? $m[2] : "http://$m[3]");
        $text = htmlspecialchars("$m[2]$m[3]");
        return "<a rel='nofollow' href='$url'>$text</a>";
    },
    $input);
}

第一个捕获组匹配一个 HTML 标记。如果已定义表达式(未更改的 HTML 标记),则表达式将替换为第一个捕获组,否则将替换为指向第二个或第三个捕获组的链接。

演示:输入:

<img src='http://foo'>www.test.com/?x&y

输出:

<img src='http://foo'><a rel='nofollow' href='http://www.test.com/?x&amp;y'>www.test.com/?x&amp;y</a>
于 2013-08-06T09:07:14.910 回答