preg_replace, чтобы заглавная буква после цитаты

У меня есть такие имена:

$str = 'JAMES "JIMMY" SMITH' 

Я запускаю strtolower , затем ucwords , который возвращает это:

 $proper_str = 'James "jimmy" Smith' 

Я хотел бы использовать вторую букву слов, в которой первая буква является двойной цитатой. Вот регулярное выражение. Похоже, strtoupper не работает – regexp просто возвращает неизменное оригинальное выражение.

 $proper_str = preg_replace('/"([az])/',strtoupper('$1'),$proper_str); 

Любые подсказки? Благодаря!!

Используйте модификатор e для оценки подстановки:

 preg_replace('/"[az]/e', 'strtoupper("$0")', $proper_str) 

Где $0 содержит совпадение всего шаблона, так что " и строчная буква. Но это не имеет значения, так как " не изменяется при отправке через strtoupper .

Вероятно, лучший способ сделать это – использовать preg_replace_callback() :

 $str = 'JAMES "JIMMY" SMITH'; echo preg_replace_callback('!\b[az]!', 'upper', $str); function upper($matches) { return strtoupper($matches[0]); } 

Вы можете использовать флаг e (eval) на preg_replace() но я вообще советую против него. В частности, при работе с внешним вводом это потенциально чрезвычайно опасно.

Используйте preg_replace_callback Но вам не нужно добавлять дополнительную именованную функцию, а использовать анонимную функцию.

 $str = 'JAMES "JIMMY" SMITH'; echo preg_replace_callback('/\b[az]/', function ($matches) { return strtoupper($matches[0]); }, $str); 

Использование /e устаревает с PHP 5.5 и не работает в PHP 7

Что-то вроде этого может сделать трюк:

 preg_replace("/(\w+)/e", "ucwords(strtolower('$1'))", $proper_str); 

Я делаю это без регулярного выражения, как часть моей пользовательской функции ucwords() . Предполагая, что в строке появится не более двух кавычек:

 $parts = explode('"', $string, 3); if(isset($parts[2])) $string = $parts[0].'"'.ucfirst($parts[1]).'"'.ucfirst($parts[2]); else if(isset($parts[1])) $string = $parts[0].'"'.ucfirst($parts[1]); 

Вы должны сделать это:

 $proper_str = preg_replace_callback( '/"([az])/', function($m){return strtoupper($m[1]);}, $proper_str ); 

Вы не должны использовать «eval ()» по соображениям безопасности.

Во всяком случае, модификатор «e» для патента устарел. См. Документацию по PHP .

 echo ucwords(mb_strtolower('JAMES "JIMMY" SMITH', 'UTF-8'), ' "'); // James "Jimmy" Smith 

ucwords() имеет второй параметр разделителя, дополнительные разделители содержат символы разделителя слов. Используйте пробел '' и 'как разделитель там, и "Jimmy" будет правильно распознан.