4

所以,我知道有很多关于 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;
?>

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

4

2 回答 2

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函数确实需要分隔符。末尾的i使其不区分大小写

更新

如果您#用作分隔符,则不需要转义!模式中的 ,因为使用原始模式字符串(模式没有 a #):"#$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://到 url,这样浏览器就不会认为它是相对链接。

于 2012-04-03T22:18:33.083 回答
3

我只是想从d_inevitable上面的答案中使用相同的正则表达式从字符串中获取 url,并且不希望将它们变成链接或关心字符串的其余部分,我只想要字符串中的 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;

}
于 2014-09-08T02:30:02.183 回答