所以,我知道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;
?>
有人可以帮我解决这个问题吗? 谢谢!
答案 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"
要确保链接正确,请执行以下操作:
$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;
}