PHP regex to replace word with link

I have a situation where I parse the text and replace certain phrases with links. Then I need to re-parse the string to replace the second set of phrases with links. The problem arises at this point when certain words or phrases in the second set may be substrings of phrases already replaced in the first pass.

Example : The string "blah blah grand canyon blah" becomes "blah blah <a href="#">grand canyon</a>

blah" after the first pass. The second pass might try to replace the word "canyon" with a link, so the resulting broken text reads "blah blah <a href="#">

grand <a href="#">

canyon </a></a>

blah".

So I'm trying to use preg_replace and a regex to prevent nested tags from appearing <a>

- only replacing text that isn't already in the link. I've tried regular expressions that check depending on whether there are tags </a>

further down the text, but can't get them to work.

A different approach might be required?

Thank you very much in advance! Dave

0


source to share


2 answers


This can work for all passes:

$string = preg_replace('/([^>]|^)grand canyon\b/','$1<a href=#>grand canyon</a>',$string);

      



EDIT: assuming you can afford to skip when there are things like "amazonas> grand canyon" in the text

+1


source


For the second pass, a regular expression can be used, for example:

(<a[^>]*>.*?</a>)|grand

      

This regular expression matches either a link or the word "grand". If a link is matched, it is written to the first (and only) capture group. If the group matches, just re-paste the existing link. If the word grand matches, you know it outside of the link, and you can turn it into a link.



In PHP, you can do this with preg_replace_callback:

$result = preg_replace_callback('%(<a[^>]*>.*?</a>)|grand%', compute_replacement, $subject);

function compute_replacement($groups) {
    // You can vary the replacement text for each match on-the-fly
    // $groups[0] holds the regex match
    // $groups[n] holds the match for capturing group n
    if ($groups[1]) {
        return $groups[1];
    } else {
        return "<a href='#'>$groups[0]</a>";
}

      

0


source







All Articles