链接正则表达式函数PHP大胆的火球方法

时间:2012-04-03 22:15:05

标签: php regex linkify

所以,我知道SO上有很多相关问题,但它们都不是我想要的。我正在尝试实现一个PHP函数,它将文本URL从用户生成的帖子转换为链接。我正在使用Daring Fireball的“改进”正则表达式到页面底部:http://daringfireball.net/2010/07/improved_regex_for_matching_urls 该函数不返回任何内容,我不确定原因。

<?php
if ( false === function_exists('linkify') ):   
  function linkify($str) {
$pattern = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))';     
return preg_replace($pattern, "<a href=\"\\0\" rel=\"nofollow\" target=\"_blank\">\\0</a>", $str);      
}
endif;
?>

有人可以帮我解决这个问题吗? 谢谢!

2 个答案:

答案 0 :(得分:11)

试试这个:

$pattern = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`\!()\[\]{};:\'".,<>?«»“”‘’]))';     
return preg_replace("!$pattern!i", "<a href=\"\\0\" rel=\"nofollow\" target=\"_blank\">\\0</a>", $str); 

PHP的preg函数确实需要delimiters。最后的i使其不区分大小写

更新

如果使用#作为分隔符,则无需转义模式中的!,因此使用原始模式字符串(模式没有# ):"#$pattern#i"

更新2

要确保链接正确,请执行以下操作:

$pattern = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))';
return preg_replace_callback("#$pattern#i", function($matches) {
    $input = $matches[0];
    $url = preg_match('!^https?://!i', $input) ? $input : "http://$input";
    return '<a href="' . $url . '" rel="nofollow" target="_blank">' . "$input</a>";
}, $str); 

现在会将http://附加到网址,以便浏览器不认为它是相对链接。

答案 1 :(得分:3)

我希望通过d_inevitable上面的答案使用相同的正则表达式从字符串中获取网址,并且没有想要将它们变成链接或关心字符串的其余部分,我只想要字符串中的url所以这就是我所做的。希望它有所帮助。

/**
 * Returns the urls in an array from a string.
 * This dos NOT return the string, only the urls with-in.
 */
function get_urls($str){

    $regex = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))';
    preg_match_all("#$regex#i", $str, $matches);
    $urls = $matches[0];
    return $urls;

}