Search code examples
phpregexsearch-engine

Dynamically Inserting Text Into String (PHP)


I have a PHP script that runs a search on my database based on terms put into the search box on a website. This returns a block of text. Let's say that my search term for right now is "test block". An example of my result would be this block of text:

This is a test block of text that was gathered from the database using a search query.

Now, my question is: how I can "highlight" the search term within the block of text so the user can see why this result was pulled in the first place. Using the above example, something like the following would suffice:

This is a test block of text that was gathered from the database from a search query.

I have tried a few things so far that will change the text, but the real problem I am running into has to do with case sensitivity. For example, if I used the code:

$exploded = explode(' ', $search_terms);
foreach($exploded as $word) {
    // I have to use str_ireplace so the word is actually found
    $result = str_ireplace($word, '<b>' . $word . '</b>', $result);
}

It would go through my $result and bold any instance of the words. This would look correct, as I wanted in my second example of the search result. But, in the case that the user uses "Test Block" instead of "test block", the search terms would be capitalized and appear as this:

This is a Test Block of text that was gathered from the database from a search query.

This does not work for me, especially when the user is using lower-case search terms and they happen to fall at the beginning of a sentance.

Essentially, what I need to do is find the word in the string, insert text (<b> in this example) directly in front of the word, and then insert text directly after the word (</b> in this example) while preserving the word itself from being replaced. This rules preg_replace and str_replace out I believe, so I am really stuck on what to do.

Any leads would be greatly appreciated.


Solution

  • $exploded = explode(' ', $search_terms);
    foreach($exploded as $word) {
        // I have to use str_ireplace so the word is actually found
        $result = preg_replace("/(".preg_quote($word).")/i", "<b>$1</b>", $result);
    }
    

    Pattern matching http://www.php.net/manual/en/reference.pcre.pattern.syntax.php uses certain characters like . [ ] / * + etc.. so if these occur in the pattern they need to be escaped first with pre_quote();

    Patterns start and end with delimiters to identify the pattern http://www.php.net/manual/en/regexp.reference.delimiters.php

    followed my modifiers http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php In this case i for case-insensitive

    anything in ( brackets ) is captured for use later, either in $matched parameter or in the replacement as $1 or \\1 for the first, $2 second etc..