Question

I want to replace words found in string with highlighted word keeping their case as found.

Example

$string1 = 'There are five colors';
$string2 = 'There are Five colors';

//replace five with highlighted five
$word='five';
$string1 = str_ireplace($word, '<span style="background:#ccc;">'.$word.'</span>', $string1);    
$string2 = str_ireplace($word, '<span style="background:#ccc;">'.$word.'</span>', $string2);

echo $string1.'<br>';
echo $string2;

Current output:

There are five colors
There are five colors

Expected output:

There are five colors
There are Five colors

How this can be done?

Was it helpful?

Solution

To highlight a single word case-insensitively

Use preg_replace() with the following regex:

/\b($p)\b/i

Explanation:

  • / - starting delimiter
  • \b - match a word boundary
  • ( - start of first capturing group
  • $p - the escaped search string
  • ) - end of first capturing group
  • \b - match a word boundary
  • / - ending delimiter
  • i - pattern modifier that makes the search case-insensitive

The replacement pattern can be <span style="background:#ccc;">$1</span>, where $1 is a backreference — it would contain what was matched by the first capturing group (which, in this case, is the actual word that was searched for)

Code:

$p = preg_quote($word, '/');  // The pattern to match

$string = preg_replace(
    "/\b($p)\b/i",
    '<span style="background:#ccc;">$1</span>', 
    $string
);

See it in action


To highlight an array of words case-insensitively

$words = array('five', 'colors', /* ... */);
$p = implode('|', array_map('preg_quote', $words));

$string = preg_replace(
    "/\b($p)\b/i", 
    '<span style="background:#ccc;">$1</span>', 
    $string
);

var_dump($string);

See it in action

OTHER TIPS

str_replace - case sensitive

str_ireplace - class insenstive

http://www.php.net/manual/en/function.str-replace.php

http://www.php.net/manual/en/function.str-ireplace.php

Here is the test case.

<?php

class ReplaceTest extends PHPUnit_Framework_TestCase
{

    public function testCaseSensitiveReplaceSimple()
    {
        $strings = array(
            'There are five colors',
            'There are Five colors',
        );

        $expected = array(
            'There are <span style="background:#ccc;">five</span> colors',
            'There are <span style="background:#ccc;">Five</span> colors',
        );

        $find = array(
            'five',
            'Five',
        );

        $replace = array(
            '<span style="background:#ccc;">five</span>',
            '<span style="background:#ccc;">Five</span>',
        );

        foreach ($strings as $key => $string) {
            $this->assertEquals($expected[$key], str_replace($find, $replace, $string));
        }
    }

    public function testCaseSensitiveReplaceFunction()
    {
        $strings = array(
            'There are five colors',
            'There are Five colors',
        );

        $expected = array(
            'There are <span style="background:#ccc;">five</span> colors',
            'There are <span style="background:#ccc;">Five</span> colors',
        );

        foreach ($strings as $key => $string) {
            $this->assertEquals($expected[$key], highlightString('five', $string, '<span style="background:#ccc;">$1</span>'));
        }
    }
}

/**
 * @argument $words array or string - words to that are going to be highlighted keeping case
 * @argument $string string - the search 
 * @argument $replacement string - the wrapper used for highlighting, $1 will be the word
 */
function highlightString($words, $string, $replacement)
{
    $replacements = array();
    $newwords = array();
    $key = 0;
    foreach ((array) $words AS $word)
    {
        $replacements[$key] = str_replace('$1', $word, $replacement);
        $newwords[$key] = $word;
        $key++;
        $newwords[$key] = ucfirst($word);
        $replacements[$key] = str_replace('$1', ucfirst($word), $replacement);
        $key++;
    }

    return str_replace($newwords, $replacements, $string);
}

Results

..

Time: 25 ms, Memory: 8.25Mb

OK (2 tests, 4 assertions)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top