Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

php - Auto detect links and put them into <a> tag, except when they are already in an html tag

Tags:

html

regex

url

php

I have found a solution for auto detecting links and putting them in the <a> tag here: Regex PHP - Auto-detect YouTube, image and "regular" links

Relevant part (I had to move the function outside of the preg_replace_callback call for compatibility reasons):

function put_url_in_a($arr)
    {
    if(strpos($arr[0], 'http://') !== 0)
        {
            $arr[0] = 'http://' . $arr[0];
        }
        $url = parse_url($arr[0]);

        //links
        return sprintf('<a href="%1$s">%1$s</a>', $arr[0]);
    }

$s = preg_replace_callback('#(?:https?://\S+)|(?:www.\S+)|(?:\S+\.\S+)#', 'put_url_in_a', $s);

This works fine, except when it stumbles upon a url in an tag, which it then ruins (by putting another tag into it). It also ruins embedded media.

Question: How can I exclude HTML tags from being processed by this function using, hopefully, only regular expressions?

like image 662
sbichenko Avatar asked Feb 22 '23 15:02

sbichenko


1 Answers

One option - if the URL is already in a link it must be prefixed by href=', so exclude links with a negative lookbehind assertion:

#(?<!href\=['"])(?:https?://\S+)|(?:www.\S+)|(?:\S+\.\S+)#

EDIT: -- actually the above form won't work because the URL match is too general, it'll turn things like ... into a link, incorrectly. Using my own favourite URL matching scheme seems to work correctly:

$s = preg_replace_callback('#(?<!href\=[\'"])(https?|ftp|file)://[-A-Za-z0-9+&@\#/%()?=~_|$!:,.;]*[-A-Za-z0-9+&@\#/%()=~_|$]#', 'regexp_url_search', $s);

For example: http://codepad.viper-7.com/TukPdY

$s = "The following link should be linkified: http://www.google.com but not this one: <a href='http://www.google.com'>google</a>."`

Becomes:

The following link should be linkified: <a href="http://www.google.com">http://www.google.com</a> but not this one: <a href='http://www.google.com'>google</a>.
like image 194
Hamish Avatar answered Feb 24 '23 14:02

Hamish