Search code examples
phpstringparsingpreg-replacepreg-match

PHP - update string with html links


I have a dictionary of medical words and phrases. In the definition I want to add links to other words that appear in the dictionary. preg_replace works unless the word is a phrase of two or more words. For example if this were a definition

CPR
Cardiopulmonary resuscitation is performed on patients that have suffered a HEART ATTACK.

I want a link on HEART ATTACK. However I have Heart AND Heart attack within my database so preg_replace makes a double link. The code ends up looking like this:

Cardiopulmonary resuscitation is performed on patients that have suffered
a <a href='http://www.example.com/medicaldictionary/search.php?word=<a
href='http://www.example.com/medicaldictionary/search.php?
word=heart'>heart</a> attack'><a 
href='http://www.example.com/medicaldictionary/search.php?
word=heart'>heart</a> attack</a>.

This is my PHP code...

foreach($word_array as $word)
{

        if (preg_match("/\b".$word."\b/i", $def))
        {
        $replace="<a href='http://www.example.com/medicaldictionary/search.php?word=".$word."'>".$word."</a>";
        $def = preg_replace("/\b".$word."\b/i", $replace, $def);
        } 
}

Maybe ignoring any part of the text contained within an tag? I'm not sure how to do that.


Solution

  • I ended up sorting the array of words by length, from longest to shortest. The matching words are replaced by a number between two unique characters in this case '@' and the number is associated with a html link array. And then the final loop replaces all the numbered matches with the html link.

    function sortbylength($a,$b){
        return strlen($b)-strlen($a);
    }
    usort($word_array,'sortbylength');
    //$word_array = array_reverse($word_array);
    $def_strip = strip_tags($def);
    $replace = array();
    $value = 0;
            foreach($word_array as $word)
            {
                if (preg_match("/\b".$word."\b/i", $def))
                    {
                    echo" $value = $word<BR>";
                    $replace[$value]="<a href='http://www.example.com/medicaldictionary/search.php?word=".$word."'>".$word."</a>";
                    $def = preg_replace("/\b".$word."\b/i", "@$value@", $def);
                    $value++;
                    } 
            }
            $value = 0;
        foreach($replace as $new_replace)
        {
    
            $def = str_replace("@$value@", $new_replace, $def);
            $value++;
    
        }   
    

    This is a crude way to solve this issue but it works.