Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP preg_replace: Case insensitive match with case sensitive replacement

I'm using preg_replace in PHP to find and replace specific words in a string, like this:

$subject = "Apple apple"; print preg_replace('/\bapple\b/i', 'pear', $subject); 

Which gives the result 'pear pear'.

What I'd like to be able to do is to match a word in a case insensitive way, but respect it's case when it is replaced - giving the result 'Pear pear'.

The following works, but seems a little long winded to me:

$pattern = array('/Apple\b/', '/apple\b/'); $replacement = array('Pear', 'pear'); $subject = "Apple apple"; print preg_replace($pattern, $replacement, $subject); 

Is there a better way to do this?

Update: Further to an excellent query raised below, for the purposes of this task I only want to respect 'title case' - so whether or not the first letter of a word is a capital.

like image 722
colin Avatar asked Oct 11 '13 11:10

colin


1 Answers

I have in mind this implementation for common case:

$data    = 'this is appLe and ApPle'; $search  = 'apple'; $replace = 'pear';  $data = preg_replace_callback('/\b'.$search.'\b/i', function($matches) use ($replace) {    $i=0;    return join('', array_map(function($char) use ($matches, &$i)    {       return ctype_lower($matches[0][$i++])?strtolower($char):strtoupper($char);    }, str_split($replace))); }, $data);  //var_dump($data); //"this is peaR and PeAr" 

-it's more complicated, of course, but fit original request for any position. If you're looking for only first letter, this could be an overkill (see @Jon's answer then)

like image 164
Alma Do Avatar answered Sep 22 '22 10:09

Alma Do