Replace URLs in text with HTML links

后端 未结 17 1744
栀梦
栀梦 2020-11-22 11:27

Here is a design though: For example is I put a link such as

http://example.com

in textarea. How do I get PHP t

相关标签:
17条回答
  • 2020-11-22 12:02

    While matching the full url spec is difficult, here's a regular expression that generally does a good job:

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

    To use this in preg_replace, however, you need to escape it. As so:

    $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);
    
    0 讨论(0)
  • 2020-11-22 12:05

    As I mentioned in one of the comments above my VPS, which is running php 7, started emitting warnings Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead. The buffer after the replacement was empty/false.

    I have rewritten the code and made some improvements. If you think that you should be in the author section feel free to edit the comment above the function make_links_blank name. I am intentionally not using the closing php ?> to avoid inserting whitespace in the output.

    <?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;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 12:09

    this should get you email addresses:

    $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
    )
    
    0 讨论(0)
  • 2020-11-22 12:10

    This RegEx should match any link except for these new 3+ character toplevel domains...

    {
      \\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
    

    It's not written by me, I'm not quite sure where I got it from, sorry that I can give no credit...

    0 讨论(0)
  • 2020-11-22 12:11

    This worked for me (turned one of the answers into a PHP function)

    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);
    }
    
    0 讨论(0)
提交回复
热议问题