2012-04-06 132 views
1

I found this code posted on SO to change text links into hyperlinks:正则表达式匹配,并且<a href>?

function auto_link_text($text) 
{ 
    $pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#'; 
    $callback = create_function('$matches', ' 
    $url  = array_shift($matches); 
    $url_parts = parse_url($url); 

    $text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH); 
    $text = preg_replace("/^www./", "", $text); 

    $last = -(strlen(strrchr($text, "/"))) + 1; 
    if ($last < 0) { 
     $text = substr($text, 0, $last) . "&hellip;"; 
    } 

    return sprintf(\'<a rel="nowfollow" href="%s">%s</a>\', $url, $text); 
    '); 

    return preg_replace_callback($pattern, $callback, $text); 
} 

However, it seems to change them into hyperlinks even if they are already a part of a hyperlink so you end up with something like <a href="<a href (etc). I figure what I could do is check for an already formatted hyperlink and if I don't find one, I can do that function. Or even put the check in the function. So something like:

function auto_link_text($text) 
{ 
    if preg_match(proper stuff in here){ 
     return $text; 
     }else{ 
     $pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#'; 
     $callback = create_function('$matches', ' 
    $url  = array_shift($matches); 
    $url_parts = parse_url($url); 

    $text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH); 
    $text = preg_replace("/^www./", "", $text); 

    $last = -(strlen(strrchr($text, "/"))) + 1; 
    if ($last < 0) { 
     $text = substr($text, 0, $last) . "&hellip;"; 
    } 

    return sprintf(\'<a rel="nowfollow" href="%s">%s</a>\', $url, $text); 
    '); 

    return preg_replace_callback($pattern, $callback, $text); 
} 
} 

Or perhapse the regex in the function should be changed.

+0

possible duplicate of [Automatically convert keywords to links in php](http://stackoverflow.com/questions/9929953/automatically-convert-keywords-to-links-in-php) – Anthony 2012-04-06 23:09:14

+0

Check out my [answer](http://stackoverflow.com/questions/9929953/automatically-convert-keywords-to-links-in-php/9932767#9932767). – Anthony 2012-04-06 23:09:47

+0

[Possible duplicate](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags) – c69 2012-04-06 23:09:54

回答

2

Add (?<!href=") just after the first # of your regex. This will ensure that it's not already inside a tag.

+0

This only checks if it's directly preceded by the href, but it won't check if it's somewhere inside of it or if it's in the text node. And nesting links is a bad idea. This would work if php supported wildcard lookbehinds, but it does not. Lookbehinds must be a pre-defined length. – Anthony 2012-04-06 23:12:17

+0

Yeah it does not work. – qitch 2012-04-06 23:14:08

+0

Erm... this makes sure the url is NOT preceded by 'href="', which means it is not inside an 'href' attribute. You could go more brute-forcey and just have '(? 2012-04-06 23:14:56