Regex сопоставляет любые URL в строке с и без www и создает кликабельный URL - PullRequest
0 голосов
/ 07 декабря 2018

Есть много похожих вопросов , но я до сих пор не нашел решения того, чего я пытаюсь достичь в 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:// не будет включен в отображаемый текст) и с URL без http или https созданная ссылка относится к домену, на котором я показываю страницу.Предложения?

Вот живое Демо

Редактировать: мое лучшее регулярное выражение, поэтому для любого URL с http или https это /(http|https)\:\/\/[a-zA-Z0-9\-\.]+(\.[a-zA-Z]{2,3})?(\/[A-Za-z0-9-._~!$&()*+,;=:]*)*/.Теперь мне просто нужен способ пересмотреть URL только с www.something... и преобразовать его в http://www.something... в href.

Вот еще одна живая демонстрация с различными примерами .

Редактировать 2: ответ на этот вопрос довольно хороший.Единственная проблема, с которой я до сих пор сталкиваюсь, это </p> после URL и если есть слова до и после точки (например, это).

$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 голосов
/ 07 декабря 2018

Может быть, это соответствует вашим потребностям:

$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);
0 голосов
/ 07 декабря 2018
$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>';
}
0 голосов
/ 07 декабря 2018

Ваше регулярное выражение было почти правильным!

Вы сопоставляете буквальную точку \., за которой следует 0 или более групп символов, включая точку.

Поэтому я изменил его на соответствующеебуквальная точка, за которой следуют 1 или более символов, исключая точку, которая, по-видимому, является той, которую вы хотите, вот последнее регулярное выражение:

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

Посмотрите это в действии: https://regex101.com/r/h5pUvC/3/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...