복붙노트

텍스트의 URL을 HTML 링크로 바꾸기

PHP

텍스트의 URL을 HTML 링크로 바꾸기

여기에 디자인이 있습니다. 예를 들어,

텍스트 영역. 어떻게하면 PHP가 http : // 링크인지 감지하고 다음과 같이 인쇄 할 수 있습니다.

print "<a href='http://www.example.com'>http://www.example.com</a>";

전에 이런 식으로 일하는 것을 기억합니다. 그러나 복잡한 링크에서 깨어나는 것은 어리석은 증거가 아닙니다.

또 다른 좋은 아이디어는 다음과 같은 링크가있는 경우입니다.

그렇게하도록 고쳐라.

print "<a href='http://example.com/test.php?val1=bla&val2=bla%20bla%20bla.bla'>";
print "http://example.com/test.php";
print "</a>";

이것은 하나의 생각입니다 .. stackoverflow 또한 아마 이것을 사용할 수 있습니다 : D 조

어떤 아이디어

해결법

  1. ==============================

    1.요구 사항을 살펴 보겠습니다. 하이퍼 링크로 표시하려는 사용자가 제공하는 일반 텍스트가 있습니다.

    요구 사항을 살펴 보겠습니다. 하이퍼 링크로 표시하려는 사용자가 제공하는 일반 텍스트가 있습니다.

    편집 : 이메일 주소, 인증 된 URL, 따옴표와 괄호로 묶은 URL, HTML 입력 및 업데이트 된 TLD 목록에 대한 지원을 포함하여 Bitbucket에서 최신 버전을 확인하십시오.

    Bitbucket 문제 추적기를 사용하여 버그 및 개선 요청을보고하십시오. 더 쉽게 추적 할 수 있습니다 (주석 영역을 복잡하게 만들지 않아야합니다).

    여기 내 걸릴 :

    <?php
    $text = <<<EOD
    Here are some URLs:
    stackoverflow.com/questions/1188129/pregreplace-to-detect-html-php
    Here's the answer: http://www.google.com/search?rls=en&q=42&ie=utf-8&oe=utf-8&hl=en. What was the question?
    A quick look at http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax is helpful.
    There is no place like 127.0.0.1! Except maybe http://news.bbc.co.uk/1/hi/england/surrey/8168892.stm?
    Ports: 192.168.0.1:8080, https://example.net:1234/.
    Beware of Greeks bringing internationalized top-level domains: xn--hxajbheg2az3al.xn--jxalpdlp.
    And remember.Nobody is perfect.
    
    <script>alert('Remember kids: Say no to XSS-attacks! Always HTML escape untrusted input!');</script>
    EOD;
    
    $rexProtocol = '(https?://)?';
    $rexDomain   = '((?:[-a-zA-Z0-9]{1,63}\.)+[-a-zA-Z0-9]{2,63}|(?:[0-9]{1,3}\.){3}[0-9]{1,3})';
    $rexPort     = '(:[0-9]{1,5})?';
    $rexPath     = '(/[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]*?)?';
    $rexQuery    = '(\?[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?';
    $rexFragment = '(#[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?';
    
    // Solution 1:
    
    function callback($match)
    {
        // Prepend http:// if no protocol specified
        $completeUrl = $match[1] ? $match[0] : "http://{$match[0]}";
    
        return '<a href="' . $completeUrl . '">'
            . $match[2] . $match[3] . $match[4] . '</a>';
    }
    
    print "<pre>";
    print preg_replace_callback("&\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))&",
        'callback', htmlspecialchars($text));
    print "</pre>";
    

    편집 : 다음 코드는 위의 두 가지 문제를 해결하지만, preg_match를 사용하여 preg_replace_callback을 다소 재 구현하기 때문에 좀 더 자세한 정보가 표시됩니다.

    // Solution 2:
    
    $validTlds = array_fill_keys(explode(" ", ".aero .asia .biz .cat .com .coop .edu .gov .info .int .jobs .mil .mobi .museum .name .net .org .pro .tel .travel .ac .ad .ae .af .ag .ai .al .am .an .ao .aq .ar .as .at .au .aw .ax .az .ba .bb .bd .be .bf .bg .bh .bi .bj .bm .bn .bo .br .bs .bt .bv .bw .by .bz .ca .cc .cd .cf .cg .ch .ci .ck .cl .cm .cn .co .cr .cu .cv .cx .cy .cz .de .dj .dk .dm .do .dz .ec .ee .eg .er .es .et .eu .fi .fj .fk .fm .fo .fr .ga .gb .gd .ge .gf .gg .gh .gi .gl .gm .gn .gp .gq .gr .gs .gt .gu .gw .gy .hk .hm .hn .hr .ht .hu .id .ie .il .im .in .io .iq .ir .is .it .je .jm .jo .jp .ke .kg .kh .ki .km .kn .kp .kr .kw .ky .kz .la .lb .lc .li .lk .lr .ls .lt .lu .lv .ly .ma .mc .md .me .mg .mh .mk .ml .mm .mn .mo .mp .mq .mr .ms .mt .mu .mv .mw .mx .my .mz .na .nc .ne .nf .ng .ni .nl .no .np .nr .nu .nz .om .pa .pe .pf .pg .ph .pk .pl .pm .pn .pr .ps .pt .pw .py .qa .re .ro .rs .ru .rw .sa .sb .sc .sd .se .sg .sh .si .sj .sk .sl .sm .sn .so .sr .st .su .sv .sy .sz .tc .td .tf .tg .th .tj .tk .tl .tm .tn .to .tp .tr .tt .tv .tw .tz .ua .ug .uk .us .uy .uz .va .vc .ve .vg .vi .vn .vu .wf .ws .ye .yt .yu .za .zm .zw .xn--0zwm56d .xn--11b5bs3a9aj6g .xn--80akhbyknj4f .xn--9t4b11yi5a .xn--deba0ad .xn--g6w251d .xn--hgbk6aj7f53bba .xn--hlcj6aya9esc7a .xn--jxalpdlp .xn--kgbechtv .xn--zckzah .arpa"), true);
    
    $position = 0;
    while (preg_match("{\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))}", $text, &$match, PREG_OFFSET_CAPTURE, $position))
    {
        list($url, $urlPosition) = $match[0];
    
        // Print the text leading up to the URL.
        print(htmlspecialchars(substr($text, $position, $urlPosition - $position)));
    
        $domain = $match[2][0];
        $port   = $match[3][0];
        $path   = $match[4][0];
    
        // Check if the TLD is valid - or that $domain is an IP address.
        $tld = strtolower(strrchr($domain, '.'));
        if (preg_match('{\.[0-9]{1,3}}', $tld) || isset($validTlds[$tld]))
        {
            // Prepend http:// if no protocol specified
            $completeUrl = $match[1][0] ? $url : "http://$url";
    
            // Print the hyperlink.
            printf('<a href="%s">%s</a>', htmlspecialchars($completeUrl), htmlspecialchars("$domain$port$path"));
        }
        else
        {
            // Not a valid URL.
            print(htmlspecialchars($url));
        }
    
        // Continue text parsing from after the URL.
        $position = $urlPosition + strlen($url);
    }
    
    // Print the remainder of the text.
    print(htmlspecialchars(substr($text, $position)));
    
  2. ==============================

    2.여기 내가 시도하고 테스트 한 것을 발견했습니다.

    여기 내가 시도하고 테스트 한 것을 발견했습니다.

    function make_links_blank($text)
    {
      return  preg_replace(
         array(
           '/(?(?=<a[^>]*>.+<\/a>)
                 (?:<a[^>]*>.+<\/a>)
                 |
                 ([^="\']?)((?:https?|ftp|bf2|):\/\/[^<> \n\r]+)
             )/iex',
           '/<a([^>]*)target="?[^"\']+"?/i',
           '/<a([^>]+)>/i',
           '/(^|\s)(www.[^<> \n\r]+)/iex',
           '/(([_A-Za-z0-9-]+)(\\.[_A-Za-z0-9-]+)*@([A-Za-z0-9-]+)
           (\\.[A-Za-z0-9-]+)*)/iex'
           ),
         array(
           "stripslashes((strlen('\\2')>0?'\\1<a href=\"\\2\">\\2</a>\\3':'\\0'))",
           '<a\\1',
           '<a\\1 target="_blank">',
           "stripslashes((strlen('\\2')>0?'\\1<a href=\"http://\\2\">\\2</a>\\3':'\\0'))",
           "stripslashes((strlen('\\2')>0?'<a href=\"mailto:\\0\">\\0</a>':'\\0'))"
           ),
           $text
       );
    }
    

    그것은 나를 위해 작동합니다. 그리고 이메일과 URL에서 작동합니다. 내 자신의 질문에 대답 해 주셔서 감사합니다. :(

    하지만이 작품 만이 작동합니다.

    여기에 내가 그것을 발견 링크입니다 : http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_21878567.html

    전문가 교환을 위해 미리 죄송합니다.

  3. ==============================

    3.너희들은 어떤 상황에 좋을만큼 진보하고 복잡한 것들을 이야기하고 있지만, 대부분 우리는 단순한 부주의 한 해결책이 필요하다. 이건 어때?

    너희들은 어떤 상황에 좋을만큼 진보하고 복잡한 것들을 이야기하고 있지만, 대부분 우리는 단순한 부주의 한 해결책이 필요하다. 이건 어때?

    preg_replace('/(http[s]{0,1}\:\/\/\S{4,})\s{0,}/ims', '<a href="$1" target="_blank">$1</a> ', $text_msg);
    

    그냥 시도하고 나에게 미친 URL이 그것을 만족하지 않는다는 걸 알려주십시오.

  4. ==============================

    4.다음은 함수에서 정규 표현식을 사용하는 코드입니다.

    다음은 함수에서 정규 표현식을 사용하는 코드입니다.

    <?php
    //Function definations
    function MakeUrls($str)
    {
    $find=array('`((?:https?|ftp)://\S+[[:alnum:]]/?)`si','`((?<!//)(www\.\S+[[:alnum:]]/?))`si');
    
    $replace=array('<a href="$1" target="_blank">$1</a>', '<a href="http://$1" target="_blank">$1</a>');
    
    return preg_replace($find,$replace,$str);
    }
    //Function testing
    $str="www.cloudlibz.com";
    $str=MakeUrls($str);
    echo $str;
    ?>
    
  5. ==============================

    5.나는이 기능을 사용하고 있으며, 그것은 나를 위해 일한다.

    나는이 기능을 사용하고 있으며, 그것은 나를 위해 일한다.

    function AutoLinkUrls($str,$popup = FALSE){
        if (preg_match_all("#(^|\s|\()((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches)){
            $pop = ($popup == TRUE) ? " target=\"_blank\" " : "";
            for ($i = 0; $i < count($matches['0']); $i++){
                $period = '';
                if (preg_match("|\.$|", $matches['6'][$i])){
                    $period = '.';
                    $matches['6'][$i] = substr($matches['6'][$i], 0, -1);
                }
                $str = str_replace($matches['0'][$i],
                        $matches['1'][$i].'<a href="http'.
                        $matches['4'][$i].'://'.
                        $matches['5'][$i].
                        $matches['6'][$i].'"'.$pop.'>http'.
                        $matches['4'][$i].'://'.
                        $matches['5'][$i].
                        $matches['6'][$i].'</a>'.
                        $period, $str);
            }//end for
        }//end if
        return $str;
    }//end AutoLinkUrls
    

    모든 크레딧은 - http://snipplr.com/view/68586/으로 이동합니다.

    즐겨!

  6. ==============================

    6.이 RegEx는이 새로운 3+ 캐릭터 최상위 도메인을 제외한 모든 링크와 일치해야합니다 ...

    이 RegEx는이 새로운 3+ 캐릭터 최상위 도메인을 제외한 모든 링크와 일치해야합니다 ...

    {
      \\b
      # Match the leading part (proto://hostname, or just hostname)
      (
        # http://, or https:// leading part
        (https?)://[-\\w]+(\\.\\w[-\\w]*)+
      |
        # or, try to find a hostname with more specific sub-expression
        (?i: [a-z0-9] (?:[-a-z0-9]*[a-z0-9])? \\. )+ # sub domains
        # Now ending .com, etc. For these, require lowercase
        (?-i: com\\b
            | edu\\b
            | biz\\b
            | gov\\b
            | in(?:t|fo)\\b # .int or .info
            | mil\\b
            | net\\b
            | org\\b
            | [a-z][a-z]\\.[a-z][a-z]\\b # two-letter country code
        )
      )
    
      # Allow an optional port number
      ( : \\d+ )?
    
      # The rest of the URL is optional, and begins with /
      (
        /
        # The rest are heuristics for what seems to work well
        [^.!,?;"\\'()\[\]\{\}\s\x7F-\\xFF]*
        (
          [.!,?]+ [^.!,?;"\\'()\\[\\]\{\\}\s\\x7F-\\xFF]+
        )*
      )?
    }ix
    

    그것은 내게 쓰여진 것이 아니고, 내가 어디에서 가져 왔는지 확신 할 수는 없다. 미안하지만 나는 신용을 줄 수 없다.

  7. ==============================

    7.이메일 주소를 알려줘야합니다.

    이메일 주소를 알려줘야합니다.

    $string = "bah bah steve@gmail.com foo";
    $match = preg_match('/[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+(?:\.[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+)*\@[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+(?:\.[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+)+/', $string, $array);
    print_r($array);
    
    // outputs:
    Array
    (
        [0] => steve@gmail.com
    )
    
  8. ==============================

    8.나는이 대답이 받아 들여 졌음을 알고이 질문은 꽤 오래되었지만 다른 구현을 찾는 다른 사람들에게 유용 할 수 있습니다.

    나는이 대답이 받아 들여 졌음을 알고이 질문은 꽤 오래되었지만 다른 구현을 찾는 다른 사람들에게 유용 할 수 있습니다.

    다음에 의해 게시 된 코드의 수정 된 버전입니다. Angel.King.47 on July 27,09 :

    $text = preg_replace(
     array(
       '/(^|\s|>)(www.[^<> \n\r]+)/iex',
       '/(^|\s|>)([_A-Za-z0-9-]+(\\.[A-Za-z]{2,3})?\\.[A-Za-z]{2,4}\\/[^<> \n\r]+)/iex',
       '/(?(?=<a[^>]*>.+<\/a>)(?:<a[^>]*>.+<\/a>)|([^="\']?)((?:https?):\/\/([^<> \n\r]+)))/iex'
     ),  
     array(
       "stripslashes((strlen('\\2')>0?'\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>&nbsp;\\3':'\\0'))",
       "stripslashes((strlen('\\2')>0?'\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>&nbsp;\\4':'\\0'))",
       "stripslashes((strlen('\\2')>0?'\\1<a href=\"\\2\" target=\"_blank\">\\3</a>&nbsp;':'\\0'))",
     ),  
     $text
    );
    

    변경 사항 :

    "Søren Løvborg"가 말했듯이이 함수는 URL을 벗어나지 않습니다. 그 / 그녀의 수업을 시도했지만 예상대로 작동하지 않았습니다 (사용자를 신뢰하지 않으면 그 / 그녀의 코드를 먼저 시도하십시오).

  9. ==============================

    9.위에서 언급 한 VPS는 PHP 7을 실행 중입니다. warning 경고 : preg_replace () : / e 수정자는 더 이상 지원되지 않으므로 대신 preg_replace_callback을 사용하십시오. 치환 후의 버퍼는 하늘 / 거짓이었습니다.

    위에서 언급 한 VPS는 PHP 7을 실행 중입니다. warning 경고 : preg_replace () : / e 수정자는 더 이상 지원되지 않으므로 대신 preg_replace_callback을 사용하십시오. 치환 후의 버퍼는 하늘 / 거짓이었습니다.

    코드를 다시 작성하고 몇 가지 개선 사항을 만들었습니다. 작성자 섹션에 있어야한다고 생각한다면 make_links_blank 이름 함수 위의 주석을 자유롭게 편집하십시오. 의도적으로 닫는 PHP를 사용하지 않습니까?> 출력에 공백을 삽입하지 마십시오.

    <?php
    
    class App_Updater_String_Util {
        public static function get_default_link_attribs( $regex_matches = [] ) {
            $t = ' target="_blank" ';
            return $t;
        }
    
        /**
         * App_Updater_String_Util::set_protocol();
         * @param string $link
         * @return string
         */
        public static function set_protocol( $link ) {
            if ( ! preg_match( '#^https?#si', $link ) ) {
                $link = 'http://' . $link;
            }
            return $link;
        }
    
    /**
         * Goes through text and makes whatever text that look like a link an html link
         * which opens in a new tab/window (by adding target attribute).
         * 
         * Usage: App_Updater_String_Util::make_links_blank( $text );
         * 
         * @param str $text
         * @return str
         * @see http://stackoverflow.com/questions/1188129/replace-urls-in-text-with-html-links
         * @author Angel.King.47 | http://dashee.co.uk
         * @author Svetoslav Marinov (Slavi) | http://orbisius.com
         */
        public static function make_links_blank( $text ) {
            $patterns = [
                '#(?(?=<a[^>]*>.+?<\/a>)
                     (?:<a[^>]*>.+<\/a>)
                     |
                     ([^="\']?)((?:https?|ftp):\/\/[^<> \n\r]+)
                 )#six' => function ( $matches ) {
                    $r1 = empty( $matches[1] ) ? '' : $matches[1];
                    $r2 = empty( $matches[2] ) ? '' : $matches[2];
                    $r3 = empty( $matches[3] ) ? '' : $matches[3];
    
                    $r2 = empty( $r2 ) ? '' : App_Updater_String_Util::set_protocol( $r2 );
                    $res = ! empty( $r2 ) ? "$r1<a href=\"$r2\">$r2</a>$r3" : $matches[0];
                    $res = stripslashes( $res );
    
                    return $res;
                 },
    
                '#(^|\s)((?:https?://|www\.|https?://www\.)[^<>\ \n\r]+)#six' => function ( $matches ) {
                    $r1 = empty( $matches[1] ) ? '' : $matches[1];
                    $r2 = empty( $matches[2] ) ? '' : $matches[2];
                    $r3 = empty( $matches[3] ) ? '' : $matches[3];
    
                    $r2 = ! empty( $r2 ) ? App_Updater_String_Util::set_protocol( $r2 ) : '';
                    $res = ! empty( $r2 ) ? "$r1<a href=\"$r2\">$r2</a>$r3" : $matches[0];
                    $res = stripslashes( $res );
    
                    return $res;
                },
    
                // Remove any target attribs (if any)
                '#<a([^>]*)target="?[^"\']+"?#si' => '<a\\1',
    
                // Put the target attrib
                '#<a([^>]+)>#si' => '<a\\1 target="_blank">',
    
                // Make emails clickable Mailto links
                '/(([\w\-]+)(\\.[\w\-]+)*@([\w\-]+)
                    (\\.[\w\-]+)*)/six' => function ( $matches ) {
    
                    $r = $matches[0];
                    $res = ! empty( $r ) ? "<a href=\"mailto:$r\">$r</a>" : $r;
                    $res = stripslashes( $res );
    
                    return $res;
                },
            ];
    
            foreach ( $patterns as $regex => $callback_or_replace ) {
                if ( is_callable( $callback_or_replace ) ) {
                    $text = preg_replace_callback( $regex, $callback_or_replace, $text );
                } else {
                    $text = preg_replace( $regex, $callback_or_replace, $text );
                }
            }
    
            return $text;
        }
    }
    
  10. ==============================

    10.의 라인을 따라 뭔가 :

    의 라인을 따라 뭔가 :

    <?php
    if(preg_match('@^http://(.*)\s|$@g', $textarea_url, $matches)) {
        echo '<a href=http://", $matches[1], '">', $matches[1], '</a>';
    }
    ?>
    
  11. ==============================

    11.이 클래스는 url을 텍스트로 변경하고 홈 URL을 그대로 유지합니다. 이것이 도움이되고 당신을 위해 시간을 절약하기를 바랍니다.

    이 클래스는 url을 텍스트로 변경하고 홈 URL을 그대로 유지합니다. 이것이 도움이되고 당신을 위해 시간을 절약하기를 바랍니다.

    class RegClass 
    { 
    
         function preg_callback_url($matches) 
         { 
            //var_dump($matches); 
            //Get the matched URL  text <a>text</a>
            $text = $matches[2];
            //Get the matched URL link <a href ="http://www.test.com">text</a>
            $url = $matches[1];
    
            if($url=='href ="http://www.test.com"'){
             //replace all a tag as it is
             return '<a href='.$url.' rel="nofollow"> '.$text.' </a>'; 
    
             }else{
             //replace all a tag to text
             return " $text " ;
             }
    } 
    function ParseText($text){ 
    
        $text = preg_replace( "/www\./", "http://www.", $text );
            $regex ="/http:\/\/http:\/\/www\./"
        $text = preg_replace( $regex, "http://www.", $text );
            $regex2 = "/https:\/\/http:\/\/www\./";
        $text = preg_replace( $regex2, "https://www.", $text );
    
            return preg_replace_callback('/<a\s(.+?)>(.+?)<\/a>/is',
                    array( &$this,        'preg_callback_url'), $text); 
          } 
    
    } 
    $regexp = new RegClass();
    echo $regexp->ParseText($text);
    
  12. ==============================

    12.IANA를 신뢰하려면 공식적으로 지원되는 TLD 목록을 다음과 같이 사용하십시오.

    IANA를 신뢰하려면 공식적으로 지원되는 TLD 목록을 다음과 같이 사용하십시오.

      $validTLDs = 
    explode("\n", file_get_contents('http://data.iana.org/TLD/tlds-alpha-by-domain.txt')); //get the official list of valid tlds
      array_shift($validTLDs); //throw away first line containing meta data
      array_pop($validTLDs); //throw away last element which is empty
    

    Søren Løvborg의 솔루션 # 2가 약간 덜 상세 해지고 목록을 업데이트하는 번거 로움을 덜어줍니다. 요즘에는 새로운 tld가 부주의하게 버려집니다.)

  13. ==============================

    13.이것은 나를 위해 일했다 (대답 중 하나가 PHP 함수로 바뀌었다)

    이것은 나를 위해 일했다 (대답 중 하나가 PHP 함수로 바뀌었다)

    function make_urls_from_text ($text){
       return preg_replace('/(http[s]{0,1}\:\/\/\S{4,})\s{0,}/ims', '<a href="$1" target="_blank">$1 </a>', $text);
    }
    
  14. ==============================

    14.이렇게하면 이메일을 건드리지 않고도 트위터를 처리 할 수 ​​있습니다. /(=<<=^|(?<<[[[[[[[[[[-)a-zA-Z0-9-.]))@([A-Za-z]+[A-Za-z0-9]+)/i

    이렇게하면 이메일을 건드리지 않고도 트위터를 처리 할 수 ​​있습니다. /(=<<=^|(?<<[[[[[[[[[[-)a-zA-Z0-9-.]))@([A-Za-z]+[A-Za-z0-9]+)/i

  15. ==============================

    15.전체 URL 사양을 일치시키는 것은 어렵지만 일반적으로 좋은 일을하는 정규 표현식은 다음과 같습니다.

    전체 URL 사양을 일치시키는 것은 어렵지만 일반적으로 좋은 일을하는 정규 표현식은 다음과 같습니다.

    ([\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?)
    

    그러나 이것을 preg_replace에서 사용하려면 이스케이프 처리해야합니다. 마찬가지로 :

    $pattern = "/([\\w-]+(\\.[\\w-]+)*@([a-z0-9-]+(\\.[a-z0-9-]+)*?\\.[a-z]{2,6}|(\\d{1,3}\\.){3}\\d{1,3})(:\\d{4})?)/";
    $replaced_texttext = preg_replace($pattern, '<a href="$0" title="$0">$0</a>', $text);
    
  16. from https://stackoverflow.com/questions/1188129/replace-urls-in-text-with-html-links by cc-by-sa and MIT license