【问题标题】:codeigniter auto_link doesnt add links without wwwcodeigniter 自动链接不会添加没有 www 的链接
【发布时间】:2012-02-17 11:50:06
【问题描述】:

如果我输入

www.google.comhttp://www.google.com

使用auto_link() 函数将正确添加链接..

但是,如果我输入

google.com

该功能自 www 起不起作用。部分丢失...

我如何确保它也包含这些链接??

这是来自 codeigniter 的函数:

/**
 * Auto-linker
 *
 * Automatically links URL and Email addresses.
 * Note: There's a bit of extra code here to deal with
 * URLs or emails that end in a period.  We'll strip these
 * off and add them after the link.
 *
 * @access  public
 * @param   string  the string
 * @param   string  the type: email, url, or both
 * @param   bool    whether to create pop-up links
 * @return  string
 */
if ( ! function_exists('auto_link'))
{
    function auto_link($str, $type = 'both', $popup = FALSE)
    {
        if ($type != 'email')
        {
            if (preg_match_all("#(^|\s|\()((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches))
            {
                $pop = ($popup == TRUE) ? " target=\"_blank\" " : "";

                for ($i = 0; $i < count($matches['0']); $i++)
                {
                    $period = '';
                    if (preg_match("|\.$|", $matches['6'][$i]))
                    {
                        $period = '.';
                        $matches['6'][$i] = substr($matches['6'][$i], 0, -1);
                    }

                    $str = str_replace($matches['0'][$i],
                                        $matches['1'][$i].'<a href="http'.
                                        $matches['4'][$i].'://'.
                                        $matches['5'][$i].
                                        $matches['6'][$i].'"'.$pop.'>http'.
                                        $matches['4'][$i].'://'.
                                        $matches['5'][$i].
                                        $matches['6'][$i].'</a>'.
                                        $period, $str);
                }
            }
        }

        if ($type != 'url')
        {
            if (preg_match_all("/([a-zA-Z0-9_\.\-\+]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $str, $matches))
            {
                for ($i = 0; $i < count($matches['0']); $i++)
                {
                    $period = '';
                    if (preg_match("|\.$|", $matches['3'][$i]))
                    {
                        $period = '.';
                        $matches['3'][$i] = substr($matches['3'][$i], 0, -1);
                    }

                    $str = str_replace($matches['0'][$i], safe_mailto($matches['1'][$i].'@'.$matches['2'][$i].'.'.$matches['3'][$i]).$period, $str);
                }
            }
        }

        return $str;
    }
}

解决方案: 函数 auto_link($str, $type = 'both', $popup = FALSE) { if ($type != 'email') { if (!preg_match_all("/^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\.([a-zA-Z])+( [a-zA-Z])+/", $str, $matches)){

        if (preg_match_all("/(?:https?\:?(?:\/\/)?|www\.)?([a-zA-Z0-9\-\.]+\.(?:.[a-z]*))/mi", $str, $matches))
        {
            $pop = ($popup == TRUE) ? " target=\"_blank\" " : "";

            for ($i = 0; $i < count($matches['0']); $i++)
            {

                            $str = str_replace($matches[0][$i],
                                                '<a href="http://'.$matches[1][0].'" class="auto_link_color">'.$matches[1][0].'</a>', $str);
            }
        }
            }else{
                for ($i = 0; $i < count($matches['0']); $i++)
                {
                    $str = str_replace($matches[0][$i], $matches[0][0], $str);
                }
            }
    }

    return $str;
}

这解决了我的问题,因此用户输入的任何链接都会找到它并添加链接...即使用户输入电子邮件,它也不会在域部分添加链接,而是将其显示为文本。

【问题讨论】:

  • 你的逻辑有缺陷,试图强迫auto_link() 这样做。 .'s 会给你造成混乱,你最终会得到不应该有的文本片段的随机 URL。即便如此,这里也不像真正的链接那样将所有 URL 格式化。想想看。你会因为某个东西是 EMAIL 还是 URL,或者只是一个带有句号的刺痛而争吵。只是不要弄乱至少没有损坏的东西,至少恕我直言。

标签: php codeigniter autolink


【解决方案1】:

自动链接应该正确捕获http://google.com。你是说这行不通?

自动链接正则表达式使用 http(s) 或 www 来指示存在链接。如果没有这些选项中的任何一个,您将不得不更改正则表达式以仅在 .com 的顶级域上检测,考虑到可能的顶级域(.net、.org、.biz 等)的广泛阵列,这将变得非常有问题。 )。如果您仔细考虑过,您可能不想更改此正则表达式,因为对所有可能的域和添加的新域的维护将比它的价值要麻烦得多。

【讨论】:

  • 我是说自动链接不会捕获 google.com 并且需要 www。或万维网。去工作。即使在我的情况下缺少 www 或 http ,如何修改正则表达式以使其工作?
  • @fxuser 你不需要修改正则表达式。只需使用 URL 帮助程序中的prep_url() 函数,然后将auto_link() 函数应用于从prep_url() 返回的值。
  • 问题是我有一堆文本,其中可能包含 url...如果我在之前添加 prep_url() 然后添加 auto_link() 它只会在前面添加 http://全文而不是链接...
  • 我没有您需要的正则表达式更改。正则表达式的整个逻辑发生了变化,因为不是从已知的起始字符串搜索到域的末尾,而是从末尾搜索并返回到前面。我真的不认为你想要它。您必须捕获顶级域的所有变体,这样维护起来很麻烦。
【解决方案2】:

很抱歉,您使用 auto_link() 的方式有误。

该参数应该是一个有效的 url 或电子邮件。只放“www.google.com”是不允许的,根本不应该工作:-)

所以你应该这样做:

auto_link('http://www.google.com')
auto_link('http://google.com')

不要在开头省略“http://”。

【讨论】:

    【解决方案3】:

    如果您不使用“http://”或“www”。作为您的“链接此”触发器,您必须对其进行编码以捕获 .com、.org、.net(以及不断扩大的可能性)。正如其他人所建议的那样,使这个 reg ex “贪婪”将匹配不应该是链接的东西。您可以根据自己的优先级来权衡取舍。

    这是我尝试的一个(非常简单的)小实验:

    <?php
    
    header("Content-type: text/plain");
    
    $text = 'http://google.com
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in urna auctor tellus consequat cursus.
    Cras malesuada magna eget felis accumsan vel dictum urna sodales. Vestibulum erat ante, rutrum et
    aliquet vel, convallis eu google.com. Phasellus interdum velit at urna google.com porta. Donec at interdum
    nibh. Fusce ultricies varius elit id egestas. Suspendisse dolor risus, vulputate vel rutrum in,
    http://google.com et nisi. Etiam non massa non neque lacinia adipiscing sed nec metus. Sed fermentum ultricies
    dui at porta. Duis at lacinia tortor. Nam mi est, mollis sed viverra et, mollis ac lorem. In mattis
    lacinia tempor.
    
    Sed in luctus nunc. Mauris nec tincidunt dui. Vivamus interdum, velit sed lobortis lobortis, nulla dui
    vestibulum dui, eu tincidunt arcu felis et massa. google.COM vitae porta felis. Sed sit amet magna augue.
    Aenean dignissim tempus porta. Donec ultrices lectus ac sapien gravida sodales. Quisque malesuada
    sagittis rhoncus. Vestibulum mattis auctor ligula, eu tempus odio hendrerit in. Ut vel elit ipsum. Sed
    ante lorem, www.google.com et dictum nec, ultricies a lorem.
    ';
    
    $domains = 'com|org|net';
    
    if ( !preg_match_all('#([\S]*)(\.('.$domains.']))#i', $text, $matches))
    {
        die('no matches');
    }
    
    print_r($matches);
    

    输出:

    Array
    (
        [0] => Array
            (
                [0] => http://google.com
                [1] => google.com
                [2] => google.com
                [3] => http://google.com
                [4] => google.COM
                [5] => www.google.com
            )
    
        [1] => Array
            (
                [0] => http://google
                [1] => google
                [2] => google
                [3] => http://google
                [4] => google
                [5] => www.google
            )
    
        [2] => Array
            (
                [0] => .com
                [1] => .com
                [2] => .com
                [3] => .com
                [4] => .COM
                [5] => .com
            )
    
        [3] => Array
            (
                [0] => com
                [1] => com
                [2] => com
                [3] => com
                [4] => COM
                [5] => com
            )
    
    )
    

    【讨论】:

      【解决方案4】:
      function auto_link($str, $type = 'both', $popup = FALSE)
      {
          if ($type != 'email')
          {
                  if (!preg_match_all("/^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\\.([a-zA-Z])+([a-zA-Z])+/", $str, $matches)){
      
              if (preg_match_all("/(?:https?\:?(?:\/\/)?|www\.)?([a-zA-Z0-9\-\.]+\.(?:.[a-z]*))/mi", $str, $matches))
              {
                  $pop = ($popup == TRUE) ? " target=\"_blank\" " : "";
      
                  for ($i = 0; $i < count($matches['0']); $i++)
                  {
      
                                  $str = str_replace($matches[0][$i],
                                                      '<a href="http://'.$matches[1][0].'" class="auto_link_color">'.$matches[1][0].'</a>', $str);
                  }
              }
                  }else{
                      for ($i = 0; $i < count($matches['0']); $i++)
                      {
                          $str = str_replace($matches[0][$i], $matches[0][0], $str);
                      }
                  }
          }
      
          return $str;
      }
      

      这解决了我的问题,因此用户输入的任何链接都会找到它并添加链接...即使用户输入电子邮件,它也不会在域部分添加链接,而是将其显示为文本。

      【讨论】:

        猜你喜欢
        • 2014-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多