正则表达式匹配带有和不带有www的字符串中的任何URL,并创建可点击的URL

时间:2018-12-06 21:05:49

标签: php regex

many similar questions,但是我仍然没有找到解决方法来解决我试图用php实现的问题。我preg_match_all一个字符串,它可以包含以各种方式编写的URL,但也包含不匹配的文本。我需要匹配的是:

www.something.com 
https://something.com
http://something.com
https://www.something.com
http://www.something.com

URL后面的任何/..../....,但不是:

www.something.com</p> // this should match everything until the '</p>'
www.something.com. // this should match everything until the '.'

到目前为止,我到目前为止是

/((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a-zA-Z0-9\&\.\/\?\:@\-_=#])*/

和功能

if(preg_match_all("/((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a-zA-Z0-9\&\.\/\?\:@\-_=#])*/",$text,$urls)){
    foreach($urls[0]as $url ){
        $text = str_replace($url,'<a href="'.$url.'">'.$url.'</a>',$text);
    }
}

但是这会给http://www....(在显示的文本中不包含http://)和没有创建的httphttps的URL带来问题链接是相对于我在其上显示页面的域的。有什么建议吗?

这是现场直播的Demo

编辑:我最好的正则表达式,因此,对于任何带有httphttps的URL,都是/(http|https)\:\/\/[a-zA-Z0-9\-\.]+(\.[a-zA-Z]{2,3})?(\/[A-Za-z0-9-._~!$&()*+,;=:]*)*/。现在,我只需要一种仅用www.something...来对URL进行正则表达式并将其转换为http://www.something...中的href的方法。

这里还有另一个live demo with different examples

编辑2: answer from this question非常好。我仍然遇到的唯一问题是URL后面的</p>以及点前后是否有单词(例如this)。

$url = '@(http)?(s)?(://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@';
$string = preg_replace($url, '<a href="http$2://$4" target="_blank" title="$0">$0</a>', $string);
echo $string;

3 个答案:

答案 0 :(得分:1)

也许这符合您的需求:

$text = preg_replace_callback('~(https?://|www)[a-z\d.-]+[\w/.?=&%:#]*\w~i', function($m) {
    $prefix = stripos($m[0], 'www') === 0 ? 'http://' : '';
    return "<a href='{$prefix}{$m[0]}'>{$m[0]}</a>";
}, $text);

答案 1 :(得分:0)

您的正则表达式几乎正确!

您要匹配的是文字点\.,后跟0个或更多的字符组,包括点。

因此,我将其更改为匹配文字点,然后是1个或多个字符(不包括您想要的点),这是最终的正则表达式:

((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a-zA-Z0-9\&\/\?\:@\-_=#])+

查看实际效果: https://regex101.com/r/h5pUvC/3/

答案 2 :(得分:0)

$text =  "<p>Some string www.test.com with urls http://test.com in it http://www.test.com. </p>";
$text = preg_replace_callback("@(http)?(s)?(://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@", 'replace_callback', $text);

function replace_callback($matches){
    return '<a href="' . $matches[0] . '" target="_blank">' . $matches[0] . '</a>';
}