Найти URL в строке и превратить в ссылку - PullRequest
0 голосов
/ 10 октября 2019

Я использую код, указанный на этой странице , чтобы просмотреть строку и превратить URL в ссылку HTML.

Это работает довольно хорошо, но есть небольшая проблемас его «заменой».

Проблема возникает, когда у меня есть почти идентичные ссылки. Например:

https://example.com/page.php?goto=200 и https://example.com/page.php

Все будет хорошо с первой ссылкой, но вторая создаст тег <a> в первой <a>tag.

Первый запуск

<a href="https://example.com/page.php?goto=200">https://example.com/page.php?goto=200</a>

Второй

<a href="<a href="https://example.com/page.php">https://example.com/page.php</a>?goto=200"><a href="https://example.com/page.php">https://example.com/page.php</a>?goto=200</a>

Поскольку он также заменяет только что созданную ссылку html.

Как этого избежать?

<?php

function turnUrlIntoHyperlink($string){

    //The Regular Expression filter
    $reg_exUrl = "/(?i)\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))/";

    // Check if there is a url in the text
    if(preg_match_all($reg_exUrl, $string, $url)) {

        // Loop through all matches
        foreach($url[0] as $newLinks){
            if(strstr( $newLinks, ":" ) === false){
                $link = 'http://'.$newLinks;
            }else{
                $link = $newLinks;
            }

            // Create Search and Replace strings
            $search  = $newLinks;
            $replace = '<a href="'.$link.'" title="'.$newLinks.'" target="_blank">'.$link.'</a>';
            $string = str_replace($search, $replace, $string);
}
    }

    //Return result
    return $string;
}
?>

Ответы [ 2 ]

0 голосов
/ 10 октября 2019

Я немного изменил заменяющую часть, так как я не смог заставить предложенное регулярное выражение работать.

Возможно, это можно сделать лучше, но я все еще учусь:)

function turnUrlIntoHyperlink($string){

    //The Regular Expression filter
    $reg_exUrl = "/(?i)\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))/";

    // Check if there is a url in the text
    if(preg_match_all($reg_exUrl, $string, $url)) {

        // Loop through all matches
        foreach($url[0] as $key => $newLinks){

            if(strstr( $newLinks, ":" ) === false){
                $url = 'https://'.$newLinks;
            }else{
                $url = $newLinks;
            }

            // Create Search and Replace strings
            $replace .= '<a href="'.$url.'" title="'.$url.'" target="_blank" class="external">'.$url.'</a>,';
            $newLinks = '/'.preg_quote($newLinks, '/').'/';
            $string = preg_replace($newLinks, '{'.$key.'}', $string, 1);

        }
        $arr_replace = explode(',', $replace);
        foreach ($arr_replace as $key => $link) {
            $string = str_replace('{'.$key.'}', $link, $string);
        }
    }

    //Return result
    return $string;
}
0 голосов
/ 10 октября 2019

В начале регулярного выражения необходимо добавить идентификатор пробела \s, также удалите \b, поскольку \b возвращает только последнее совпадение. Вы можете записать регулярное выражение в виде:

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

отметьте это: https://regex101.com/r/YFQPlZ/1

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