Joe
Joe

Reputation: 7

Can Regex/preg_replace be used to add an anchor tag to a keyword?

I would like to be able to switch this...

My sample [a id="keyword" href="someURLkeyword"] test keyword test[/a] link this keyword here.

To...

My sample [a id="keyword" href="someURLkeyword"] test keyword test[/a] link this [a href="url"]keyword[/a] here.

I can't simply replace all instances of "keyword" because some are used in or within an existing anchor tag.

Note: Using PHP5 preg_replace on Linux.

Upvotes: 1

Views: 1370

Answers (2)

mcrumley
mcrumley

Reputation: 5700

Using regular expressions may not be the best way to solve this problem, but here is a quick solution:

function link_keywords($str, $keyword, $url) {
    $keyword = preg_quote($keyword, '/');
    $url = htmlspecialchars($url);

    // Use split the string on all <a> tags, keeping the matched delimiters:
    $split_str = preg_split('#(<a\s.*?</a>)#i', $str, -1, PREG_SPLIT_DELIM_CAPTURE);

    // loop through the results and process the sections between <a> tags
    $result = '';
    foreach ($split_str as $sub_str) {
        if (preg_match('#^<a\s.*?</a>$#i', $sub_str)) {
            $result .= $sub_str;
        } else {
            // split on all remaining tags
            $split_sub_str = preg_split('/(<.+?>)/', $sub_str, -1, PREG_SPLIT_DELIM_CAPTURE);
            foreach ($split_sub_str as $sub_sub_str) {
                if (preg_match('/^<.+>$/', $sub_sub_str)) {
                    $result .= $sub_sub_str;
                } else {
                    $result .= preg_replace('/'.$keyword.'/', '<a href="'.$url.'">$0</a>', $sub_sub_str);
                }
            }
        }
    }
    return $result;
}

The general idea is to split the string into links and everything else. Then split everything outside of a link tag into tags and plain text and insert links into the plain text. That will prevent [p class="keyword"] from being expanded to [p class="[a href="url"]keyword[/a]"].

Again, I would try to find a simpler solution that does not involve regular expressions.

Upvotes: 2

troelskn
troelskn

Reputation: 117517

You can't do this with regular expressions alone. Regular expressions are context free -- they simply match a pattern, without regard to the surroundings. To do what you want, you need to parse the source out into an abstract representation, and then transfor it into your target output.

Upvotes: 2

Related Questions