检测到链接时出现regexp错误

时间:2014-05-13 18:55:40

标签: php regex hyperlink protocols

我使用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);
}

2 个答案:

答案 0 :(得分:1)

实际上,这不是关于你的正则表达式而是关于链接的更多信息。

在主播中,浏览器知道链接引用互联网上其他地址的唯一方法是提供URIhttp://表示URI(方案http)。

请记住,在大多数文件系统上,文件可以包含多个点,因此当您说转到www.google.com 时,浏览器会认为您的文件名为www扩展程序.google.com是您要去的地方。它与foo.tar.gz没有区别。

如果有的话,只添加一个//,在浏览器术语中表示预先添加此页面具有的任何协议/方案(http / https / file )到URL并视为外部链接

将其翻译为Regex

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

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

//

小组((((?:([A-Za-z]{3,9}):)?(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)现在拥有协议(即4)。在其后面添加http:之后的任何内容(始终)。

答案 1 :(得分:0)

这只是因为你没有提供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

获取我的代码段
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

Ya,更新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";