【问题标题】:ERROR with regexp while detecting the link检测链接时出现正则表达式错误
【发布时间】:2014-07-01 14:34:21
【问题描述】:

我正在使用 xampp 来测试我的网站,并使用正则表达式来检测链接并将它们转换为可点击的格式,但是当用户输入 www.google.com 而不是 https://www.google.com 时,链接会重定向到 localhost/www.google。 com

我的代码

function link_detect($text){

  $ex = "/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/i";
  return preg_replace($ex,'<a class="click_link" href="$1" target="_blank">$1</a>', $text);
}

【问题讨论】:

    标签: php regex hyperlink protocols


    【解决方案1】:

    实际上,这与您的正则表达式无关,而与您的链接有关。

    在锚点中,浏览器知道链接指向互联网上其他地方的站点的唯一方法是提供URIhttp:// 表示一个 URI(使用方案 http)。

    请记住,在大多数文件系统中,一个文件可以有多个点,所以当您说 转到www.google.com 时,浏览器会认为您的意思是一个名为 www 的文件,扩展名为 @987654326 @是你想去的地方。和foo.tar.gz没什么区别。

    如果有的话,只需在 URL 前添加一个 //,这在浏览器术语中意味着 将此页面具有的任何协议/方案 (http/https/file) 添加到 URL 并视为外部链接

    将其翻译成正则表达式

    一种可能的解决方案是尝试检测 (((https?|file):)?\/\/)?,从中提取第 4 组(https?|file,它将找到 httphttpsfile),然后将其添加到链接的开头,总是提供//

    这样,如果没有指定方案,链接仍然会告诉浏览器使用当前页面使用的默认方案并且链接是外部 .

    ((((?:([A-Za-z]{3,9}):)?(?:\/\/)?)(?:[\-;:&amp;=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&amp;=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&amp;;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)

    4 组现在拥有协议(即http:)。将其中的任何内容添加到您的链接后面加上//总是)。

    【讨论】:

    • 我更愿意将其视为文件www.google,扩展名为.com。但是,荣誉,实际上是可读的。
    • @ebyrob 也许 :) 我知道当我编写构建系统脚本并需要更改我使用 indexOf('.') 而不是 lastIndexOf('.') 的扩展时。做.tar.gz -> .tar.zip 是没有意义的。取决于你如何看待事物!
    • .tgzftw!
    【解决方案2】:

    只是因为你没有提供http://

    试试这个

    function link_detect($text){
    
      $ex = "/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/i";
      return preg_replace($ex,'<a class="click_link" href="http://$1" target="_blank">$1</a>', $text);
    }
    

    或者,你可以从这个gist我的sn-p

    function text_to_link($str = NULL)
    {
        if($str == '' OR !preg_match('/(http|www\.|@)/i', $str))
        {
            return $str;
        }
    
        $lines      = explode("\n", $str); 
        $return     = '';
        while (list($k,$l) = each($lines)) { 
            $l = preg_replace("/([ \t]|^)www\./i", "\\1http://www.", $l);
            $l = preg_replace("/([ \t]|^)ftp\./i", "\\1ftp://ftp.", $l);
            $l = preg_replace("/(http:\/\/[^ )!]+)/i", "<a href=\"\\1\">\\1</a>", $l);
            $l = preg_replace("/(https:\/\/[^ )!]+)/i", "<a href=\"\\1\">\\1</a>", $l);
            $l = preg_replace("/(ftp:\/\/[^ )!]+)/i", "<a href=\"\\1\">\\1</a>", $l);
            $l = preg_replace("/([-a-z0-9_]+(\.[_a-z0-9-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)+))/i", "<a href=\"mailto:\\1\">\\1</a>", $l);
            $return .= $l."\n";
        }
    
        return $return;
    }
    
    
    /*
    *
    * ------------------------------------------
    * Link
    * <a href="http://www.yours.com">http://www.yours.com</a>
    * <a href="https://www.yours_with_ssl.com">https://www.yours_with_ssl.com</a>
    * ------------------------------------------
    *
    */
    text_to_link('http://yours.com');
    text_to_link('https://yours_with_ssl.com');
    
    
    /*
    *
    * ------------------------------------------
    * FTP
    * <a href="ftp://username:password@yours.com">ftp://username:password@yours.com</a>
    * ------------------------------------------
    *
    */
    text_to_link('ftp://username:password@yours.com');
    
    /*
    *
    * ------------------------------------------
    * Email
    * <a href="mailto:w.kristories@gmail.com">mailto:w.kristories@gmail.com</a>
    * ------------------------------------------
    *
    */
    text_to_link('w.kristories@gmail.com');
    

    更新

    来自@Mr.coder 的评论

    但如果一个链接已经附加了http:// 协议,那么href 会是什么样的http://http://www.google.com

    是的,更新我对link_detect() 的回答。

    function link_detect($text)
    {
      // $ex = "/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/i";
      // return preg_replace($ex,'<a class="click_link" href="http://$1" 
      $ex = preg_replace("/([ \t]|^)www\./i", "\\1http://www.", $text); // Replace www to http://www
      $ex = preg_replace("/(http:\/\/[^ )!]+)/i", "<a target=\"_blank\" href=\"\\1\">\\1</a>", $ex);
      return $ex;
    }
    
    echo link_detect('www.google.com') . "\n";
    echo link_detect('http://google.com') . "\n";
    echo link_detect('http://www.google.com') . "\n";
    

    【讨论】:

    • 翻译:你的正则表达式没有这样做。任何 HTML 页面中没有http:// 的任何链接都将转到本地主机(或目录)。示例:&lt;html&gt;&lt;body&gt;&lt;a href="www.google.com"&gt;www.google.com&lt;/a&gt;&lt;/body&gt;&lt;/html&gt;
    • 但如果链接已经附加了http:// 协议,那么href 会是什么样的http://http://www.google.com
    • 你的sn-p或我的地址在哪里
    猜你喜欢
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 2019-10-01
    • 2011-10-23
    • 1970-01-01
    • 2012-03-27
    相关资源
    最近更新 更多