PHP preg замена: совпадение без учета регистра с заменой с учетом регистра


Я использую 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);

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

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

Author: colin, 2013-10-11

3 answers

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

$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 тогда)

 8
Author: Alma Do, 2013-10-11 12:09:33

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

$replacer = function($matches) {
    return ctype_lower($matches[0][0]) ? 'pear' : 'Pear';
};

print preg_replace_callback('/\bapple\b/i', $replacer, $subject);

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

 10
Author: Jon, 2016-01-17 22:22:33

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

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

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

 3
Author: Luke Madhanga, 2016-10-02 21:59:49