У меня есть такие имена:
$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" будет правильно распознан.