views:

31

answers:

4

In the function below, I want to match the keyword case insensitive (should match "Blue Yoga Mats" and "blue yoga mats")...

However, it currently only matches if the keyword is the same case.

$mykeyword = "Blue Yoga Mats";

$post->post_content = preg_replace_callback("/\b($mykeyword)\b/","doReplace", $post->post_content);

// the callback function
function doReplace($matches)
{
    static $count = 0;

    // switch on $count and later increment $count.
    switch($count++) {
        case 0: return '<b>'.$matches[1].'</b>';   // 1st instance, wrap in bold
        case 1: return '<em>'.$matches[1].'</em>'; // 2nd instance, wrap in italics
        case 2: return '<u>'.$matches[1].'</u>'; // 3rd instance, wrap in underline
        default: return $matches[1];              // don't change others.
            }
    }
+3  A: 

Simply add the i modifier to your regex to make it perform a case insensitive match:

"/\b($mykeyword)\b/i"

By the way, if you haven't already, you need to escape special regex characters from your keyword. In case any are present, they could screw up your regex and cause PHP warnings/errors. Call preg_quote() before you perform the replacement:

$mykeyword_escaped = preg_quote($mykeyword, '/');
$post->post_content = preg_replace_callback("/\b($mykeyword_escaped)\b/i","doReplace", $post->post_content);
BoltClock
+1 for the bit about `preg_quote` (I added it to a comment, but seeing as you have it here, there's no need for the comment)...
ircmaxell
Thanks for the quick response! Any idea how to keep the function from matching keywords that have already been matched and wrapped? Example, every time I save the content, it wraps another set of tags around each keyword. If I change my keyword to " keyword" it works but misses the case when the keyword is the first character of the content block.
Scott B
I just fixed my code. Missed out the modifier in the second code block, silly me.
BoltClock
@Scott: That'd be much trickier given how your callback function currently works. You'd have to modify the regex to not match the wrapping tags, but you're currently using a static counter within the function to decide what to replace with, so you're wrapping subsequent matches with different tags (I'm confusing myself now)...
BoltClock
I'll just leave it with my workaround for now. Adding the empty space at the front of the keyword eliminates the duplicate match problem as long as the keyword is not the first word in the content block.
Scott B
A: 

Add the "i" modifier to your regexp:

/\b($mykeyword)\b/i
icanhasserver
A: 
$post->post_content = preg_replace_callback("/\b($mykeyword)\b/i","doReplace", $post->post_content);

Use TOKENregexpTOKENi to perform case-insensitive searches.

See Pattern Modifiers in the PHP manual for full details on modifiers.

danlefree
A: 

Use the /i modifier:

$post->post_content = preg_replace_callback("/\b($mykeyword)\b/i","doReplace", $post->post_content);
willell