PHP preg_replace: Нечувствительность к регистру с чувствительностью к регистру

Я использую preg_replace в PHP для поиска и замены определенных слов в строке, например:

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

Это дает результат «грушевая груша».

То, что я хотел бы сделать, – это совместить слово в нечувствительном к регистру образом, но уважайте его, когда он заменяется – давая результат «Грушевая груша».

Следующие работы, но, кажется, немного на меня намотали:

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

Есть лучший способ сделать это?

Обновление. В дополнение к отличному запросу, поднятому ниже, для целей этой задачи я хочу только уважать «титульный код» – так ли первая буква слова является капиталом.

Я имею в виду эту реализацию для общего случая:

 $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" 

– Это сложнее, конечно, но подходит исходный запрос для любой позиции. Если вы ищете только первую букву, это может быть излишним (см. Затем ответ @ Jon)

Вы можете сделать это с помощью preg_replace_callback , но это еще более длительное время:

 $replacer = function($matches) { return ctype_lower($matches[0][0]) ? 'pear' : 'Pear'; }; print preg_replace_callback('/\bapple\b/i', $replacer, $subject); 

Этот код просто рассматривает капитализацию первого символа матча, чтобы определить, что заменить; вы могли бы адаптировать код, чтобы сделать что-то более активное.

Это решение, которое я использовал:

 $result = preg_replace("/\b(foo)\b/i", "<strong>$1</strong>", $original); 

В лучших словах, которые я могу, я попытаюсь объяснить, почему это работает: обернуть свой поисковый запрос с помощью () означает, что я хочу получить доступ к этому значению позже. Поскольку это первый элемент в pars в RegEx, он доступен с помощью $1 , как вы можете видеть в параметре подстановки